看看这个ZeroMQ HelloWorldClient.hs代码片段:
forM_ [1..10] $ \i -> do
liftIO . putStrLn $ "Sending Hello " ++ show i ++ "…"
send requester [] "Hello"
_ <- receive requester
liftIO . putStrLn $ "Received World " ++ show i
Run Code Online (Sandbox Code Playgroud)
有什么理由_ <- receive requester不写成receive requester?
另外,一般来说,有没有理由使用_ <- f(where f : Monad m => m a)而不是f?
我有一些功能
bar :: MyType -> MyType -> [MyType]
Run Code Online (Sandbox Code Playgroud)
我想有另一个功能:
foo :: [MyType] -> [MyType]
foo xs = do x <- xs
y <- xs
bar x y
Run Code Online (Sandbox Code Playgroud)
是否可以在foo不使用do符号的情况下编写?我在考虑类似的东西,liftA2但那不起作用.
所以,我想prog使用>>/ >>=bindings而不是do和重写给定的函数<-:
prog :: IO Int
prog =
do putStrLn "Hello there! How old are you?"
age <- (readLn :: IO Int)
let agedays = show $ age * 365
putStrLn $ "So you are at least than " ++ agedays ++ " days old."
return (read agedays)
Run Code Online (Sandbox Code Playgroud)
重写更简单的功能对我来说不是问题,但是readLn :: IO Int让我头疼...
我的建议是:
prog :: IO Int
prog =
putStrLn "Hello there!How old are you?" >>
readLn::IO >>=
let …Run Code Online (Sandbox Code Playgroud) 我知道您应该将要对结果执行的操作包装在monad中,而不是从monad中拆包。
我找不到如何做到这一点的任何对白痴友好的例子。
例如,我想做这样的事情:
myFunction = do
c <- getChar
if (c == 'q')
then putStrLn "take action 1"
else putStrLn "take action 2"
Run Code Online (Sandbox Code Playgroud)
但是您不能直接将char文字与IO Char进行比较。
GHCi版本是8.4.4。
错误信息:
[2之1]编译Lib(/Users/jamesstrieter/hask-tink/src/Lib.hs,已解释)
/Users/jamesstrieter/hask-tink/src/Lib.hs:66:18:错误:•无法将预期类型'IO char'与实际类型'Char'匹配•在第二个参数'(==)' ,即“ q”在表达式中:x =='q'在'what2do'的等式中:what2do x = x =='q'•相关绑定包括x :: IO字符(绑定在/ Users / jamesstrieter /hask-tink/src/Lib.hs:66:9)what2do :: IO字符-> Bool(绑定到/Users/jamesstrieter/hask-tink/src/Lib.hs:66:1)| 66 | what2do x = x =='q'| ^^^失败,未加载任何模块。
我正在使用Haskell编写程序,该程序需要简单的保存和加载功能。当我调用保存功能时,我需要将一个字符串放入文本文件中。调用load时,需要将字符串从文本文件中拉出。
我知道Haskell中围绕IO的复杂性。从网上的一些阅读中,我发现可以通过“主要”功能来实现。但是,我似乎只能实现保存或加载……不能同时实现。
例如,我目前具有以下功能,用于从文件读取。
main = do
contents <- readFile "Test.txt"
putStrLn contents
Run Code Online (Sandbox Code Playgroud)
我还如何实现写功能?是否必须在同一功能内?还是可以分开?另外,有没有办法让我命名函数load / save?当我实际上想调用“加载”或“保存”时必须调用“ main”是很烦的。
我在网上找不到有人同时实现这两个功能的任何示例,而我发现的任何一个实现都总是通过主要功能执行。
任何建议将不胜感激。
我正在尝试使用此处的代码创建和使用字典:
import Data.List (lookup)
insert :: Eq a => (a,b) -> [(a,b)] -> [(a,b)]
insert (a,b) [] = [(a,b)]
insert (a,b) ((c,d):rest) = if a == c
then (a,b) : rest
else (c,d) : insert (a,b) rest
dict :: [(String, String)]
dict = [("", "")]
main = do
insert ("onekey", "onevalue") dict
print dict
print $ lookup "onekey" dict
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误:
$ runghc rndict.hs
rndict.hs:22:1: error:
• Couldn't match expected type ‘IO t0’ with actual type ‘[()]’
• In …Run Code Online (Sandbox Code Playgroud) dictionary haskell compiler-errors type-mismatch do-notation
我有这个程序,它只是打印出命令行参数。
echoArgs :: IO ()
echoArgs = do
line <- getArgs
print line
Run Code Online (Sandbox Code Playgroud)
我想知道的是为什么当我输入时会失败:
echoArgs :: IO ()
echoArgs = do
line <- getArgs
putStrLn line
Run Code Online (Sandbox Code Playgroud)
以及为什么当我将其更改为以下内容时它不起作用:
echoArgs :: IO String
echoArgs = do
line <- getArgs
let line' = read line :: String
putStrLn line'
Run Code Online (Sandbox Code Playgroud) 我完全是 Haskell 的初学者,我来自 js 环境,我有一个简单的数组students,我想将一些学生对象推入其中,但遗憾的是 Haskell 不支持对象(如果有我可以做到的方法,请指导我)所以尝试制作一个读取用户输入(数组)并将其推入students数组的简单程序,这是我尝试过的:
main :: IO()
main = do
let students = []
studentArray <- getLine
students ++ studentArray
print(students)
Run Code Online (Sandbox Code Playgroud)
但抛出以下错误: Couldn't match type `[]' with `IO'
这个问题与这篇文章有关:Understanding do notation for simple Reader monad: a <- (*2), b <- (+10), return (a+b)
我不在乎一种语言是否难以理解,如果它有望解决一些易于理解的语言给我们带来的问题。我被承诺在 Haskell(和其他函数式语言)中不可能改变状态是一个游戏规则改变者,我确实相信这一点。我的代码中有太多与状态相关的错误,我完全同意这篇文章,即在 OOP 语言中对对象的交互进行推理几乎是不可能的,因为它们可以改变状态,因此为了推理代码,我们应该考虑这些状态的所有可能排列。
但是,我发现对 Haskell monad 的推理也非常困难。正如您在我链接的问题的答案中所见,我们需要一个大图来理解 do 符号的 3 行。>>=为了理解代码,我总是打开stackit.io手动去糖化do符号并一步一步地编写do符号的应用程序。
这个问题或多或少是这样的:在大多数情况下,当我们有S a >>= f我们必须展开a从S并应用f它。然而,f实际上在形式中或多或少是另一回事S a >>= g,我们也必须解开等等。人脑不是那样工作的,我们不能轻易地把这些东西应用到头脑中然后停下来,把它们放在大脑的堆栈中,然后继续应用剩下的东西,>>=直到我们到达终点。当到达终点时,我们将所有这些东西存储在大脑的堆栈中并将它们粘合在一起。
因此,我一定是做错了什么。必须有一种简单的方法来理解>>=大脑中的“成分”。我知道 do 表示法非常简单,但我只能将其视为一种轻松编写>>=作文的方法。当我看到do符号时,我只是将它翻译成一堆 >>=. 我不认为它是理解代码的一种单独方式。如果有办法,我希望有人告诉我。
所以问题是:如何阅读do符号?
我可以像这样替换 do-block 吗:
do
...
pure ...
Run Code Online (Sandbox Code Playgroud)
其中最后一行是“纯粹”的东西,带有这样的 ado 块:
ado
...
in ...
Run Code Online (Sandbox Code Playgroud)
?
我知道do只需要Bind而不是Monad(即Applicative),但我们已经在使用pure,所以我们已经Applicative。
do-notation ×10
haskell ×9
monads ×5
io ×3
io-monad ×2
dictionary ×1
function ×1
linked-list ×1
purescript ×1
typeclass ×1