Haskell IO单子示例
考虑以下Haskell IO单子示例,haskell,Haskell,考虑以下IO代码: ghci> let x = return 100 :: IO Int ghci> :t do { a <- x; print a; return 500 } do { a <- x; print a; return 500 } :: Num b => IO b 在上述示例中,我的理解是: x具有类型IO Int print a具有类型IO() return 500具有类型Num b=>IO b 在我看来,IO()不符合类型,numb=>i
IO
代码:
ghci> let x = return 100 :: IO Int
ghci> :t do { a <- x; print a; return 500 }
do { a <- x; print a; return 500 } :: Num b => IO b
在上述示例中,我的理解是:
具有类型x
IO Int
具有类型print a
IO()
具有类型return 500
Num b=>IO b
IO()
不符合类型,numb=>iob
。另外,据我所知,IO Int
不符合Num b=>IO b
如果这个观察是有效的,那么为什么要编译这个代码呢?每一行,即>=
,不得符合MB
,其中m
等于IO和b
等于Num b=>b
?是否打印>>返回500
>
的签名是(>>)::Monad m=>ma->mb->mb
,它与所看到的内容同步。do{a>=print>>返回500
>
的签名是(>>)::Monad m=>ma->mb->mb
,它与所看到的内容同步。您将desugars发布到下面的代码
x >>= (\a ->
print a >>
return 500)
或者,扩展(>>)
然后,您可以看到在对(>>=)
的不同调用中,a
和b
的类型不一定相同
- 在第一个调用中:
具有typex
,IO Int
具有type\a->print a>=(\\\u->return 500)
,因此我们的Num c=>Int->IO c
类型签名中的(>=)
是a
,而Int
是b
(带有c
限制)Num
- 在第二个调用中:
具有typeprint a
,而IO()
具有type\\u500
(Num c=>()->IO c
部分是通过尝试匹配()
)的签名推断出来的,因此(>=)
的类型签名中的(>=)
是a
,而()
是b
(仍然有c
限制)Num
- 您将desugars发布到下面的代码中
x >>= (\a ->
print a >>
return 500)
或者,扩展(>>)
然后,您可以看到在对(>>=)
的不同调用中,a
和b
的类型不一定相同
- 在第一个调用中:
具有typex
,IO Int
具有type\a->print a>=(\\\u->return 500)
,因此我们的Num c=>Int->IO c
类型签名中的(>=)
是a
,而Int
是b
(带有c
限制)Num
- 在第二个调用中:
具有typeprint a
,而IO()
具有type\\u500
(Num c=>()->IO c
部分是通过尝试匹配()
)的签名推断出来的,因此(>=)
的类型签名中的(>=)
是a
,而()
是b
(仍然有c
限制)Num
IO()
需要坚持类型?为什么IO Int
不符合约束条件?请注意,do
块的已删除版本使用>=
和>
。还要注意中间类型对于这里的结果类型并不重要,例如f=const 3.words.show
具有类型(Show a,Num b)=>a->b
,虽然words
有typeString->[String]
。为什么IO()
需要坚持类型?为什么IO Int
不符合约束条件?请注意,do
块的已删除版本使用>=
和>
。还要注意中间类型对于这里的结果类型并不重要,例如f=const 3.words.show
具有类型(显示a,Num b)=>a->b
,尽管单词
的类型为String->[String]
。
x >>= (\a ->
print a >>= (\_ ->
return 500))