我尝试在 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
但是因为我没有得到答案,所以我在这里问这个问题。