Haskell 哈斯克尔
使用Haskell 哈斯克尔,haskell,monads,if-statement,do-notation,Haskell,Monads,If Statement,Do Notation,使用do-符号: Type error in application *** Expression : putStr "0" putStr "0" *** Term : putStr *** Type : String -> IO () *** Does not match : a -> b -> c -> d do 对此的经典解释是,你想从两个现有的一元值中形成一个新的一元值。让我们看看putStr的类型 do a
do
-符号:
Type error in application
*** Expression : putStr "0" putStr "0"
*** Term : putStr
*** Type : String -> IO ()
*** Does not match : a -> b -> c -> d
do
对此的经典解释是,你想从两个现有的一元值中形成一个新的一元值。让我们看看putStr的类型
do
a <- something
if a
then
do
cmd1
cmd2
else
do
cmd3
cmd4
cmd5 -- this comes after the 'then' and the 'else'
这意味着它是一个黑匣子,当执行时,它将“返回”单元类型的(唯一)值。一元计算背后的关键思想是,您有一个组合器>=
,它将两个一元表达式组合在一起,将一个表达式的结果输入下一个表达式(更准确地说,是一个创建下一个表达式的函数)。一个关键点是IO
库提供了这个组合器,这意味着
- 它[IO在本例中]可以跳过第二个一元值,例如当第一个一元值引发异常时
- 如果
IO
aRealWorld
状态包含打开的文件句柄等,它可以传递其他数据
- 它可以“确保”第一个先求值,这与大多数lambda表达式求值不同,在lambda表达式求值中,最外层(“last”)项首先展开。这一点对于打印非常重要,因为第一次打印需要首先改变世界
在你的情况下,像这样使用它
IO ()
当然,有一条捷径
putStr "0" >>= (\c -> putStr "0")
还有do符号,正如另一张海报所提到的,它更像是一种语法糖
putStr "0" >> putStr "0"
对于这个人为的例子,您也可以使用如下案例:
do
putStr "0"
putStr "0"
使用do语法可能更容易阅读,但我想先在不使用do语法的情况下展示它,只是为了强调do语法只是语法,实际上并没有做任何特殊的事情。这里是do语法
main = readLn >>= \input -> case input of
0 -> putStrLn "0"
1 -> putStrLn "0"
2 -> putStr "0"
>> putStrLn "0"
3 -> putStr "0"
>> putStr "0"
>> putStrLn "0"
_ -> putStrLn "infinite"
main=do
输入putStrLn“0”
1->putStrLn“0”
2->执行putStr“0”
putStrLn“0”
3->执行putStr“0”
putStr“0”
putStrLn“0”
_->putStrLn“无限”
我更喜欢将do
与else
和放在同一行,然后
@fuzzxl对,我也是。但我想强调的是,这不是什么神奇的,然后再做语法。这只是if-then-else
表达式分支中的正常do
-符号。我只是在开始上课时使用了do
。。这种方法解决了一些关于术语的小问题:单词“monad”用作没有其他限定词的名词,通常只指具有monad
实例的类型构造函数。某些类型的ma
值,其中m
是单子,通常称为其他值。@camcann,关于术语:我见过“命令”和“动作”。在“putstrs
中,是一个打印字符串s的IO
操作。@Lambdageek:这对IO
和其他一些操作很好,但应用于列表之类的东西听起来很傻。“一元价值”之类的变体似乎在一般情况下使用,但这很笨拙。我更喜欢“一元价值”而不是“行动”。当我们达成一致意见时,我会编辑条目。@gatoatigrado:唉,如果通用术语中有一个好的通用术语,我一开始就会这么说。我建议你要么用“动作”来表示IO,要么用“一元值”或“一元中的值”来表示。但仅仅是“单子”就容易造成混乱。我确实记得有人建议“mote”,这很可爱,但我不认为它流行起来。:)这并不能回答您的问题,但我希望您认识到,将其作为模式匹配编写会更好<代码>0->…1->…
@Chuck IO的案例输入与模式匹配是否可能,因为它是一个IO程序
main = readLn >>= \input -> case input of
0 -> putStrLn "0"
1 -> putStrLn "0"
2 -> putStr "0"
>> putStrLn "0"
3 -> putStr "0"
>> putStr "0"
>> putStrLn "0"
_ -> putStrLn "infinite"
main = do
input <- readLn
case input of
0 -> putStrLn "0"
1 -> putStrLn "0"
2 -> do putStr "0"
putStrLn "0"
3 -> do putStr "0"
putStr "0"
putStrLn "0"
_ -> putStrLn "infinite"