Van*_*uel 4 io monads haskell pointfree
为什么countInFile1和countInFile3有编译器错误,当countInFile0和countInFile2没有时.这四个都是一回事.
count :: String -> String -> Int
count w = length . filter (==w) . words
present :: String -> String -> IO String
present w = return . show . count w
-- VALID: pointed readFile, regular present
countInFile0 :: String -> FilePath -> IO ()
countInFile0 w f = putStrLn =<< present w =<< readFile f
-- INVALID: pointless readFile, regular present
countInFile1 :: String -> FilePath -> IO ()
countInFile1 w = putStrLn =<< present w =<< readFile
-- VALID: pointed readFile, inline present
countInFile2 :: String -> FilePath -> IO ()
countInFile2 w f = putStrLn =<< (return . show . count w) =<< readFile f
-- INVALID: pointless readFile, inline present
countInFile3 :: String -> FilePath -> IO ()
countInFile3 w = putStrLn =<< (return . show . count w) =<< readFile
main = do
countInFile0 "bulldogs" "bulldogs.txt"
countInFile1 "bulldogs" "bulldogs.txt"
countInFile2 "bulldogs" "bulldogs.txt"
countInFile3 "bulldogs" "bulldogs.txt"
Run Code Online (Sandbox Code Playgroud)
另外,为什么countInFile3有这个额外的错误,countInFile1没有:
example_one.hs:21:27:
No instance for (Monad ((->) FilePath))
arising from a use of `=<<'
Possible fix:
add an instance declaration for (Monad ((->) FilePath))
In the expression:
putStrLn =<< (return . show . count w) =<< readFile
In an equation for `countInFile3':
countInFile3 w
= putStrLn =<< (return . show . count w) =<< readFile
Run Code Online (Sandbox Code Playgroud)
既countInFile1
和countInFile3
,因为你正在撰写形式的三件事情a -> IO b
,你在想所谓Kleisli组成的,在<=<
自Control.Monad
.尝试
countInFile1 w = putStrLn <=< present w <=< readFile
countInFile3 w = putStrLn <=< return . show . count w <=< readFile
Run Code Online (Sandbox Code Playgroud)
或者你可以countInFile3 w file = ... =<< readFile file
像其他地方一样写作.readFile file
(带参数)是一个IO String
,因此可以通过>>=
或传递=<<
给任何一个String -> IO b
.但这并不像你想要的那样猛烈. readFile
只是它本身就是一个FilePath -> IO String
所以它可以>=>
与任何人String -> IO b
一起制作一个FilePath -> IO b
等等b -> IO c
,在你的情况下以一个结尾FilePath -> IO ()
第二个错误来自ghc尝试读取=<< readFile
,为此需要readFile
mb为某些monad m,所以它安定下来Monad ((->) FilePath)
(这实际上有意义Control.Monad.Instances
,但只会延迟得到第一个错误.)
如果你将file
参数添加到这些参数,那么,
countInFile1 w file = (putStrLn <=< present w <=< readFile) file
Run Code Online (Sandbox Code Playgroud)
它是可能是因为您解析countInFile2
和countInFile0
这种方式,而诠释=<<
的<=<
时候实际上他们是像这样:
countInFile0 w file = putStrLn =<< present w =<< (readFile file)
Run Code Online (Sandbox Code Playgroud)
差异与之间的差异相同
f n = (even . (+1) . (*3)) n
Run Code Online (Sandbox Code Playgroud)
或者等价的
f = even . (+1) . (3*)
Run Code Online (Sandbox Code Playgroud)
而另一方面
f n = even $ (+1) $ 3 * n -- cp. your 0 and 2
Run Code Online (Sandbox Code Playgroud)
如果你n
从这里删除双方
f = even $ (+1) $ (3*) -- cp. your 1 and 3
Run Code Online (Sandbox Code Playgroud)
你会得到类似于你所看到的类型错误:
No instance for (Integral (a0 -> a0)) arising from a use of `even'
Run Code Online (Sandbox Code Playgroud)
在您使用的地方,$
您需要参数n
- 如您使用的位置>>=
或=<<
您需要参数file
.随着.
,如<=<
,你不知道.
归档时间: |
|
查看次数: |
162 次 |
最近记录: |