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

时间:2017-09-14 06:15:56

标签: haskell

编译:

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与子表达式的类型签名中的类型不同。如何使子表达式的类型引用上面给出的多态类型?

1 个答案:

答案 0 :(得分:5)

这是the ScopedTypeVariables language extension的目的。你需要做两件事:

  1. 启用the ScopedTypeVariables language extension,可能是将{-# LANGUAGE ScopedTypeVariables #-}添加到文件顶部。

  2. 使用foo将类型变量置于forall的类型签名范围内。

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

    {-# LANGUAGE ScopedTypeVariables #-}
    
    foo :: forall a. (Bounded a, Enum a) => a -> Int
    foo _ = length ([minBound .. maxBound] :: [a])
    

    这应该成功编译。

    †有关为何需要这样做的信息,请参阅this answer