如何指定子表达式的多态类型?

rub*_*ion 2 haskell

这编译:

foo :: (Bounded a,Enum a) => a -> Int
foo x = length ([minBound .. x] ++ drop 1 [x .. maxBound])
Run Code Online (Sandbox Code Playgroud)

这不编译:

foo :: (Bounded a,Enum a) => a -> Int
foo x = length ([minBound .. maxBound] :: [a])
Run Code Online (Sandbox Code Playgroud)

我认为第二个例子没有编译,因为a类型签名中的类型与子表达式的类型签名中的类型不同.如何使子表达式的类型引用上面给出的多态类型?

Ale*_*ing 5

这是目的ScopedTypeVariables语言扩展.你需要做两件事:

  1. 启用ScopedTypeVariables语言扩展可能通过增加,{-# LANGUAGE ScopedTypeVariables #-}到文件的顶部.

  2. 使用类型变量将类型变量放入foo类型签名的范围内forall.

完成这两项更改后,您应该最终得到:

{-# LANGUAGE ScopedTypeVariables #-}

foo :: forall a. (Bounded a, Enum a) => a -> Int
foo _ = length ([minBound .. maxBound] :: [a])
Run Code Online (Sandbox Code Playgroud)

这应该成功编译.


†有关为何需要此信息的信息,请参阅此答案.