2017-09-14 48 views
2

這將編譯:如何指定子表達式的多態類型?

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是不一樣的一箇中子表達式的類型簽名。我怎樣才能使子表達式的類型引用上面給出的多態類型?

+2

我想你正在尋找ScopedTypeVariables擴展。 – gigabytes

回答

5

這就是the ScopedTypeVariables language extension的用途。你需要做兩件事情:

  1. 啓用the ScopedTypeVariables language extension,可能是通過增加{-# LANGUAGE ScopedTypeVariables #-}到文件的頂部。

  2. 使用forall將類型變量帶入foo的類型簽名的作用域中。

使得無論這些變化後,你應該結束了這一點:

{-# LANGUAGE ScopedTypeVariables #-} 

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

這應該編譯成功。


†關於爲什麼這是必要的信息,請參閱this answer

+1

或'[minBound .. maxBound :: a]' – chi

相關問題