Der einfachste Weg fmap
zu verwenden, die den folgenden Typ hat:
fmap :: (Functor f) => (a -> b) -> f a -> f b
IO
implementiert Functor
, was bedeutet, dass wir die oben genannte Art durch Substitution IO
für f
erhalten spezialisieren können:
fmap :: (a -> b) -> IO a -> IO b
Mit anderen Worten, wir nehmen eine Funktion, die a
s zu b
s konvertiert, und verwenden, um das Ergebnis einer IO
Aktion zu ändern. Zum Beispiel:
getLine :: IO String
>>> getLine
Test<Enter>
Test
>>> fmap (map toUpper) getLine
Test<Enter>
TEST
Was ist gerade dort passiert? Nun, map toUpper
Typ hat:
map toUpper :: String -> String
Es hat eine String
als Argument und gibt eine String
als Ergebnis. Insbesondere wird die gesamte Zeichenfolge großgeschrieben. Jetzt
, schauen wir uns die Art von fmap (map toUpper)
aussehen:
fmap (map toUpper) :: IO String -> IO String
Wir haben ein Upgrade unsere Funktion auf IO
Werten zu arbeiten. Es transformiert das Ergebnis einer IO
Aktion, um eine Großbuchstaben-Zeichenfolge zurückzugeben.
Wir können auch implementieren diese do
Notation, zu:
getUpperCase :: IO String
getUpperCase = do
str <- getLine
return (map toUpper str)
>>> getUpperCase
Test<Enter>
TEST
Es stellt sich heraus, dass jede Monade die folgende Eigenschaft hat:
fmap f m = do
x <- m
return (f x)
Mit anderen Worten, wenn irgendein Typ Monad
implementiert, Dann sollte es immer in der Lage sein, auch Functor
mit der obigen Definition zu implementieren.In der Tat können wir immer die liftM
als Implementierung Standard verwenden von fmap
:
liftM :: (Monad m) => (a -> b) -> m a -> m b
liftM f m = do
x <- m
return (f x)
liftM
ist identisch mit fmap
, außer spezialisiert auf Monaden, die als functors nicht so allgemein sind.
Also, wenn Sie das Ergebnis eines IO
Aktion zu transformieren möchten, können Sie entweder:
fmap
,
liftM
oder
do
Notation
Es ist wirklich zu dir welche du bevorzugst. Ich empfehle persönlich fmap
.
welche Tutorials haben Sie gelesen - jede Einführung zu IO in Haskell deckt Ihre Frage ab. Die Lösung besteht darin, die IO-Monade zu erstellen. – epsilonhalbe
Danke. Ich habe das Problem gelöst. Siehe unten: –