我嘗試在Haskell中開發嵌入式特定於領域的語言。 我不想類型簽名作爲::Rational
所有的時間,所以我嘗試使用默認 聲明我的類型:使用「默認」聲明重載數字操作
corresponding section in Haskell report
這正常工作在這個簡單的例子:
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:答案可能與
answer given to a question on Stack Overflow
,但我不知道以何種方式。
PS2:我已經問的問題在一週前就哈斯克爾 - 咖啡:
http://www.haskell.org/pipermail/haskell-cafe/2013-September/108956.html
但正如我沒有獲得答案,我在這裏問的問題。
感謝散熱器爲您的答案。是不是typeclass約束而不是指數(在我的例子中,等於'2')?實際上類型類型'Foo'的類型變量'a'對應於指數,而不是基數。無論如何,如果我是對的,原因是因爲'^^'的正確參數有一個類型類型約束'Foo',它不是標準類型類型,因此不可能有默認類型。我對嗎?感謝您的解決方案。 – user2827908
@ user2827908是的,沒錯。我修正了文字。 – Heatsink