I try to develop an embedded domain specific language in Haskell. I don't want to type signatures as ::Rational
all the time, so I try to use a default declaration for my types:
corresponding section in Haskell report
This works correctly in this simple example:
default (Integer, Double) -- "default default"
mag :: Float -> Float -> Float
mag x y = sqrt( x^2 + y^2 )
main = do
print $ mag 1 1
Indeed we obtain sqrt(2) as a result. If we replace the default declaration by:
default ()
, we obtain errors at compilation as expected: the type of 2
is ambiguous.
Now let us consider a more complicated example:
{-# 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
I would expect it to work correctly, but we obtain errors concerning the ambiguous type of 2
. Why? How to make my default declaration work? And if I want to give the priority to Rational
instead of Integer
? Indeed, this should be possible because we don't get any error below.
$ ghci
> import Data.Ratio
> 2::Rational
2 % 1
PS1: The answer may be related to
answer given to a question on Stack Overflow
but I don't know in which way.
PS2: I already asked the question one week ago on Haskell-Cafe:
http://www.haskell.org/pipermail/haskell-cafe/2013-September/108956.html
But as I obtained no answer, I ask the question here.
Haskell is very conservative about type class defaulting: it only chooses a default instance of classes defined in the Prelude. In your case, there is a Foo
constraint on the type of the literal 2, so the compiler won't choose a default instance for it.
You can declare types in a syntactically lighter way by writing monomorphic functions. For example, the following compiles without errors:
rat :: Rational -> Rational
rat x = x
mag :: Float -> Float -> Float
mag x y = sqrt( x ^^ rat 2 + y ^^ rat 2 )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.