我想知道我们是否可以在函数外部使用 where ? 例如
fun::Int->Int
fun n = n + 1
main = do
fun x where x = 30
显然,当我编译它时不起作用
我只想将x声明为乐趣的局部变量
答案 0 :(得分:5)
您的函数的类型错误,无法用作do
块中的最终表达式。它需要返回一个Monad m => m Int
值,而不仅仅是一个Int
。由于main
(通常使用)必须是IO
动作,因此这意味着m
应该是IO
。
fun :: Int -> IO Int
fun n = return (n + 1)
在这种情况下,let
比where
更合适。
main = do
let x = 30 in fun x
现在,x
的范围仅在 中,用于对fun
的调用。如果你写了
main = do
let x = 30
fun x
然后,从技术上讲,x
属于其余do
块的范围,而不仅仅是对fun
的调用。尽管共享相同的关键字let
,但let
块中的do
与常规let
表达式之间还是有明显的区别。 (关系是
do
let name = value
foo
等同于
let name = value
in do
foo
)
请注意,do
本身不会不会创建单值;假定 一元属性的各种算子只是简单的语法糖。快速概述:
do { x <- y; foo x; }
成为y >>= (\x -> foo x)
。do { foo; bar; }
成为foo >> bar
。do { let x = y; foo; }
成为let x = y in do foo
do foo
成为foo
。与您的代码最相关的是规则4; do
块中的单个表达式等同于表达式本身,这意味着您可以剥离do
。只有在do
块被废止之后,Haskell才开始对结果进行类型检查。