2009-05-28 15 views

Odpowiedz

38

Dobrze

f :: [String] -> [Int] 
f = map read 

Nie?

+0

to działało! :) tnx – pier

2

Ogólna odpowiedź na takie pytania polega na podzieleniu zadania na części: [String] -> [Int] wygląda na połączenie String -> Int i [a] -> [b]. Hoogle (połączone) daje pewne rezultaty dla obu, zobaczmy ...

$ hoogle 'string -> INT'
Test.HUnit.Base Etykieta :: String -> Węzeł błąd
Prelude: [Char] -> długość
Prelude :: [A] -> Int
długość Data.List :: [A] -> Int
Data.Char digitToInt :: Char -> Int
Data.Char ord :: Char -> Int
Debug.Trace trace :: String -> a -> a
Network.Buf ferType buf_fromStr :: BufferOp a -> String -> a
Network.Socket wysłać :: Socket -> String -> IO Int
Graphics.UI.GLUT.Callbacks.Window Char :: Char -> Key
Prelude odczytu :: Odczyt => String -> a
Text.Read czytać :: Odczyt => String -> a
Data.String fromString :: IsString a => String -> a
GHC.Exts fromString :: IsString a => String -> a
Control.Monad.Trans.Error strMsg :: błąd a => String -> a
Control.Monad.Error.Class strMsg :: błąd a => String -> a
. ..

Ugh, dużo śmieci. Możemy najpierw wyeliminować te z pakietów masz nic wspólnego z ...

błędzie Prelude :: [Char] -> długość
Prelude :: [a] -> int
długość Data.List :: [a] -> Int
Data.Char digitToInt :: Char -> Int
Data.Char ord :: Char -> Int
Prelude czytać :: Odczyt => String -> a
Tekst. Czytaj przeczytaj: Read a => String -> a
Data.String fromString :: IsString a => String -> a
Text.Printf printf :: PrintfType r => String -> r

error brzmi prawie jak to, co chcesz. length nie. digitToInt? Brzmi nieźle - i działa w rzeczywistości, ale tylko z liczbami jednocyfrowymi. read? Być może nie jest to nazwa, której się spodziewałeś, ale jeśli myślisz o tym, to jest to słuszne: konwersja łańcucha na coś bardziej znaczącego (jak liczba) jest jak czytanie jakiegoś tekstu.

Prawo, po drugiej stronie Hoogle daje nam coś chcemy aż przodu:

$ hoogle '[a] -> [b]'
Prelude map :: (a -> b) -> [a] -> [b]
Data.List map :: (a -> b) -> [a] -> [b]
Prelude concatMap :: (a -> [b]) - > [a] -> [b]
Data.List concatMap :: (a -> [b]) -> [a] -> [b]
Data.Maybe mapMaybe :: (a -> Maybe b) -> [a] -> [b]
Cykl wstępny e :: [a] -> [a]
Cykl Data.List :: [a] -> [a]
Prelude init :: [a] -> [a]
Data.List init :: [ a] -> [a]
Prelude odwrócić :: [a] -> [a]

Jak widać większość z tych funkcji są nazywane coś z "map", który nie może ponownie być nazwa spodziewałeś się - ale widocznie tak właśnie nazywa się ta operacja! Ten, którego szukasz, jest dość prosty.

Wreszcie, musimy połączyć te dwie funkcje. map potrzebuje innej funkcji jako swojego pierwszego argumentu - cóż, to oczywiście read! Więc wystarczy zastosować map do read. Następnym argumentem jest lista [a] s: aha, już skończyliśmy!

Można to sprawdzić poprzez uruchomienie aż ghci:

Prelude>: t mapę czytać
mapie Czytaj :: Czytaj b => [String] -> [b]

Jest wciąż ten b tutaj zamiast Int, ale nieważne, że: b może być dowolnym typem, który chcesz! - pod warunkiem, że ma instancję Read. Int posiada:

Prelude>: i Int
danych Int = GHC.Types.I # GHC.Prim.Int # - Zdefiniowane w `GHC.Types'
instancji ograniczony Int - Zdefiniowane w` GHC.Enum '
instancja Enum Int - Zdefiniowane w `GHC.Enum'
instancji Eq Int - Zdefiniowane w` GHC.Classes'
instancji Integral Int - Zdefiniowane w `GHC.Real”
instancji Num Int - Zdefiniowana w `GHC.Num '
instancja Ord Int - Zdefiniowana w` GHC.Classes'
instancja Odczytaj Int - Zdefiniowana w `GHC.Read '
instancja Real Int - Zdefiniowana w instancji` GHC.Real'
Pokaż Int - Zdefiniowana w `GHC.Show”

21

ta zawodzi:

map read ["1","2"] 
[*Exception: Prelude.read: no parse 

Sposobem na to jest:

map (read::String->Int) ["1","2"] 
[1,2] 
:: [Int] 

Poza GHCI w pliki .hs byłoby:

let intList = map (read::String->Int) ["1","2"] 
Powiązane problemy