簡體   English   中英

Haskell Variadic函數和實例聲明

[英]Haskell Variadic Function & Instance Declarations

我試圖理解這個關於可變函數的問題的例子,並嘗試修改代碼:

class SumRes r where 
    sumOf :: Integer -> r

instance SumRes Integer where
    sumOf = id

instance (Integral a, SumRes r) => SumRes (a -> r) where
    sumOf x = sumOf . (x +) . toInteger

對此:

class SumRes r where 
    sumOf :: Int -> r

instance SumRes Int where
    sumOf = id

instance (SumRes r) => SumRes (Int -> r) where
    sumOf x = sumOf . (x +) 

我得到了Illegal instance declaration for SumRes (Int -> r)Illegal instance declaration for SumRes (Int -> r) 有人可以解釋這意味着什么,我反對的約束是什么?

你剛剛達到了Haskell標准的極限。 標准Haskell僅允許一組受限制的實例聲明 特別地,所有實例都必須是“簡單的”,因為它們是應用於零個或多個類型變量的類型

這意味着您可以擁有IntMaybeMaybe a實例。 但是,你不能擁有像Maybe Int這樣的實例。 這就是你遇到的問題:你的實例有一個類型( -> )應用於Int和變量。

但是,盡管此行為不符合標准,但它仍然有意義,因此您可以使用擴展名啟用它。 這就是FlexibleInstances所做的,明顯的警告是你的代碼不再是標准的Haskell。

在標准Haskell中,實例頭(實例中類名之后的部分)需要具有T a 1 a 2 .. a n ,其中T是類型構造函數,而a i是不同的類型變量。

編譯器抱怨,因為你的實例頭是(->) Int r ,而Int不是一個類型變量。

在GHC中,可以使用FlexibleInstances擴展來解除此限制,這樣做的唯一真正缺點是可能缺乏可移植性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM