编译:
foo :: (Bounded a,Enum a) => a -> Int
foo x = length ([minBound .. x] ++ drop 1 [x .. maxBound])
这不编译:
foo :: (Bounded a,Enum a) => a -> Int
foo x = length ([minBound .. maxBound] :: [a])
我认为第二个例子没有编译,因为类型签名中的类型a
与子表达式的类型签名中的类型不同。如何使子表达式的类型引用上面给出的多态类型?
答案 0 :(得分:5)
这是the ScopedTypeVariables
language extension的目的。你需要做两件事:
启用the ScopedTypeVariables
language extension,可能是将{-# LANGUAGE ScopedTypeVariables #-}
添加到文件顶部。
使用foo
将类型变量置于forall
的类型签名范围内。†
完成这两项更改后,您应该最终得到:
{-# LANGUAGE ScopedTypeVariables #-}
foo :: forall a. (Bounded a, Enum a) => a -> Int
foo _ = length ([minBound .. maxBound] :: [a])
这应该成功编译。
†有关为何需要这样做的信息,请参阅this answer。