[英]using “default” declaration for overloaded numeric operations
我嘗試在Haskell中開發嵌入式領域特定語言。 我不想一直將簽名鍵入為::Rational
,所以我嘗試為我的類型使用默認聲明:
在以下簡單示例中,這可以正常工作:
default (Integer, Double) -- "default default"
mag :: Float -> Float -> Float
mag x y = sqrt( x^2 + y^2 )
main = do
print $ mag 1 1
實際上,我們獲得了sqrt(2)作為結果。 如果我們將默認聲明替換為:
default ()
,我們會按預期在編譯時獲得錯誤: 2
的類型不明確。
現在讓我們考慮一個更復雜的示例:
{-# LANGUAGE FlexibleInstances #-}
import Prelude hiding ((^^))
import Data.Ratio
default (Integer, Rational, Double)
class (Num a) => Foo a where
(^^) :: Num b => b -> a -> b
instance Foo Rational where
(^^) x r = x ^ n
where n = 2*numerator r -- dummy calculation
instance Foo Integer where
(^^) x n = x ^ n
mag :: Float -> Float -> Float
mag x y = sqrt( x ^^ 2 + y ^^ 2 )
main = do
print $ mag 1 1
我希望它可以正常工作,但是我們會得到有關2
的歧義類型的錯誤。 為什么? 如何使我的默認聲明生效? 如果我要優先考慮Rational
而不是Integer
? 確實,這應該是可能的,因為下面沒有任何錯誤。
$ ghci
> import Data.Ratio
> 2::Rational
2 % 1
PS1:答案可能與
但我不知道用哪種方式。
PS2:一周前,我已經在Haskell-Cafe上問過這個問題:
http://www.haskell.org/pipermail/haskell-cafe/2013-September/108956.html
但是,由於我沒有得到答案,我在這里提出問題。
Haskell對於類型類默認設置非常保守:它僅選擇Prelude中定義的類的默認實例。 在您的情況下,文字2的類型存在Foo
約束,因此編譯器不會為其選擇默認實例。
您可以通過編寫單態函數以語法上更輕松的方式聲明類型。 例如,以下編譯無錯誤:
rat :: Rational -> Rational
rat x = x
mag :: Float -> Float -> Float
mag x y = sqrt( x ^^ rat 2 + y ^^ rat 2 )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.