在Haskell函数之外的位置使用
我想知道是否可以在函数外使用where? e、 g 很明显,当我编译它时,它不起作用在Haskell函数之外的位置使用,haskell,Haskell,我想知道是否可以在函数外使用where? e、 g 很明显,当我编译它时,它不起作用 我只想将x声明为fun的局部变量您的函数的类型错误,无法用作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
我只想将x声明为fun的局部变量您的函数的类型错误,无法用作
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
,但do
块中的let
与常规let
表达式之间存在明显差异。(关系是这样的
do
let name = value
foo
相当于
let name = value
in do
foo
)
请注意,
do
本身并不创建一元值;它只是假设一元属性的各种运算符的语法糖。快速概述:
do{x>=(\x->foox)
do{foo;bar;}
变成foo>>bar
do{let x=y;foo;}
在do-foo中变成let x=y
dofoo
变成foo
与您的代码最相关的是规则4;
do
块中的单个表达式等同于表达式本身,这意味着您可以剥离do
。只有在do
块被删除后,Haskell才开始键入检查结果。是否这样做?将OP的代码复制/粘贴到ghci中对我来说很好。我很抱歉我很好奇他报告的错误是什么。啊,好的观点。我修复了OP没有特别指出的另一个错误,那就是fun
使用了错误的类型,因为它在do
块中。这不是main::IO()的要求吗
?因此编译器也会拒绝使用main::IO a
(除非我记错了什么).main
只是一个可以绑定到任何东西的名称。如果它被用作完整程序的入口点,那么它必须绑定到一个IO
操作才能运行程序。在这里,更一般的monad约束仅仅来自这样一个事实:它绑定到一个由do
块定义的值。啊,好的。不,我认为原因是,do
语法(特别是,
)或monad(如调用return
)已使用。do fun x
简化为简单的fun x
。这不起作用的唯一原因是类型不匹配。您可以在此上下文中使用where
-阅读错误消息!
let name = value
in do
foo