如何在Haskell的"let"表达式中使用"type"定义值?

vik*_*ata 0 parsing haskell let

我试图定义一个特定类型的值,如"Int",但似乎Prelude不支持它?

Prelude> let c::Int = 4
Prelude| 

<interactive>:49:8:
    Illegal type signature: ‘Int’
      Perhaps you intended to use ScopedTypeVariables
    In a pattern type-signature
Prelude> let [Int]c=4
Prelude| 

<interactive>:51:5: Parse error in pattern: [Int]
Run Code Online (Sandbox Code Playgroud)

怎么纠正呢?

Ant*_*sky 7

在 Haskell 文件中,类型声明与定义分开提供,通常在之前的行中:

c :: Int    -- Type declaration
c = 4       -- Definition
Run Code Online (Sandbox Code Playgroud)

这适用于本地定义以及全局定义;你只需要确保缩进对齐。所以在这种情况下,我们有

let c :: Int
    c = 4
in c + c
Run Code Online (Sandbox Code Playgroud)

在 Haskell 中,换行符和缩进可以用大括号和分号代替,有时可以省略大括号。在 GHCi 中,输入多行输入需要一些额外的机器,您通常需要分号分隔的变体;也就是说,这将是

let c :: Int ; c = 4
Run Code Online (Sandbox Code Playgroud)

(缺少 anin是因为 GHCi 的行为有点像do块;这个 Stack Overflow 问题有更多信息。)

但是,从您的提示看来,您已经:set +m打开了,因此您也可以使用多行选项:

Prelude> let c :: Int
Prelude|     c = 4
Prelude|
Prelude>
Run Code Online (Sandbox Code Playgroud)

(此外,如果您想在之后添加类型注释,let c = 4 ; c :: Int效果很好;对于您正在处理的文件来说,这不是最佳样式。)


另外,重要的一点是:您使用的不是“Prelude”,而是GHCi,GHC 的交互式 Haskell 环境。 Prelude是,默认情况下,在所有的Haskell程序(它提供的定义导入模块BoolEq(.),等)。GHCi 的默认提示包含当前导入的所有模块的列表,因此默认情况下它是Prelude>; 但是,如果您键入import Data.Function,则提示将更改为Prelude Data.Function>