如何在IO函数中使用纯函数? : -/Haskell - 如何在IO函数中使用纯函数?
例如:我正在读文件(IO函数),我想通过使用具有参照透明度的纯函数来解析其上下文(字符串)。
似乎这样的世界,纯粹的功能和IO功能是分开的。我怎样才能弥合他们?
如何在IO函数中使用纯函数? : -/Haskell - 如何在IO函数中使用纯函数?
例如:我正在读文件(IO函数),我想通过使用具有参照透明度的纯函数来解析其上下文(字符串)。
似乎这样的世界,纯粹的功能和IO功能是分开的。我怎样才能弥合他们?
Alex Horsman帮助了我。他说:
“也许我的误解,但是这听起来很简单 做{X < - ioFunc;回报(pureFunc X)}?”
然后我解决我的问题:
import System.IO
import Data.List
getFirstPart line Nothing = line
getFirstPart line (Just index) = fst $ splitAt index line
eliminateComment line =
getFirstPart line $ elemIndex ';' line
eliminateCarriageReturn line =
getFirstPart line $ elemIndex '\r' line
eliminateEntersAndComments :: String -> String
eliminateEntersAndComments text =
concat $ map mapFunction $ lines text
where
mapFunction = (++ " ") . eliminateCarriageReturn . eliminateComment
main = do {
contents <- readFile "../DWR-operators.txt";
return (eliminateEntersAndComments contents)
}
您也可以从Control.Monad中考虑liftM函数。
一个小例子来帮助你(运行到ghci中,你是下IO单子)
$ import Control.Monad -- to emerge liftM
$ import Data.Char -- to emerge toUpper
$ :t map to Upper -- A pure function
map toUpper :: [Char] -> [Char]
$ :t liftM
liftM :: Monad m => (a1 -> r) -> m a1 -> m r
$ liftM (map toUpper) getLine
最简单的方法是使用fmap
,它具有以下类型:
fmap :: (Functor f) => (a -> b) -> f a -> f b
IO
执行Functor
,这意味着我们可以通过用IO
替代f
来专门化上述类型,以获得:
fmap :: (a -> b) -> IO a -> IO b
换句话说,我们采用一些函数将a
s转换为b
s,并使用它来更改IO
操作的结果。例如:
getLine :: IO String
>>> getLine
Test<Enter>
Test
>>> fmap (map toUpper) getLine
Test<Enter>
TEST
刚刚发生了什么?那么,map toUpper
的类型是:
map toUpper :: String -> String
它需要一个String
作为参数,并返回一个String
结果。具体来说,它将整个字符串大写。
现在,让我们看看fmap (map toUpper)
类型:
fmap (map toUpper) :: IO String -> IO String
我们已升级的函数,在IO
值工作。它将IO
操作的结果转换为返回上层字符串。
我们也可以在此使用do
符号,来实现:
getUpperCase :: IO String
getUpperCase = do
str <- getLine
return (map toUpper str)
>>> getUpperCase
Test<Enter>
TEST
事实证明,每一个单子具有以下特性:
fmap f m = do
x <- m
return (f x)
换句话说,如果任何类型实现了Monad
,那么它应该始终能够使用上述定义来实现Functor
。事实上,我们可以一直使用liftM
作为fmap
默认实现:
liftM :: (Monad m) => (a -> b) -> m a -> m b
liftM f m = do
x <- m
return (f x)
liftM
是相同的fmap
,除了专门给单子,这不是一般的函子。
所以,如果你想改变一个IO
作用的结果,你可以使用:
fmap
,liftM
,或do
符号这是真的了给你你喜欢哪一个。我个人建议fmap
。
这不会解释如何提取IO操作的结果,而不是如何从IO操作调用纯函数* – 2015-06-11 19:56:26
实际答案如下:
main = do
val <- return (purefunc)
return
包装它在适当的单子这样做可以把它分配给VAL。
你读过什么教程 - 每一个在哈斯克尔IO介绍涵盖你的问题。解决方案是创建IO Monad。 – epsilonhalbe 2013-02-17 00:26:42
谢谢。我解决了这个问题。 Look bellow: – 2013-02-17 00:50:02