在Haskell函数之外的地方使用

时间:2018-08-22 19:11:59

标签: haskell

我想知道我们是否可以在函数外部使用 where ? 例如

fun::Int->Int
fun n = n + 1

main = do
     fun x where x = 30

显然,当我编译它时不起作用

我只想将x声明为乐趣的局部变量

1 个答案:

答案 0 :(得分:5)

您的函数的类型错误,无法用作do块中的最终表达式。它需要返回一个Monad m => m Int值,而不仅仅是一个Int。由于main(通常使用)必须是IO动作,因此这意味着m应该是IO

 fun :: Int -> IO Int
 fun n = return (n + 1)    

在这种情况下,letwhere更合适。

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本身不会不会创建单值;假定 一元属性的各种算子只是简单的语法糖。快速概述:

  1. do { x <- y; foo x; }成为y >>= (\x -> foo x)
  2. do { foo; bar; }成为foo >> bar
  3. do { let x = y; foo; }成为let x = y in do foo
  4. do foo成为foo

与您的代码最相关的是规则4; do块中的单个表达式等同于表达式本身,这意味着您可以剥离do。只有在do块被废止之后,Haskell才开始对结果进行类型检查。