views:

135

answers:

4

Possible Duplicate:
Return specific type within Haskell

This code:

class Alpha a where
    half :: Real f => a -> f

instance Alpha Double where
    half a = a/2.0

produces this error:

rigid.hs:6:13:
    Couldn't match expected type `f' against inferred type `Double'
      `f' is a rigid type variable bound by
          the type signature for `half' at rigid.hs:3:17
    In the expression: a / 2.0
    In the definition of `half': half a = a / 2.0
    In the instance declaration for `Alpha Double'
Failed, modules loaded: none.

Why?

EDIT: Figuring out the business of rigid type, I think I've arrived at a more focused question. How do I convert a Double into a value that satisfies Ord and Num? That is, a function that gets me (Ord a, Num a) => Double -> a?

+2  A: 

You are claiming that half can convert the type a into any Real type. But your half can only convert a (Double) to Double.

newacct
How do I do the following: `(Ord a, Num a) => Double -> a`?
qrest
+2  A: 

That is, a function that gets me (Ord a, Num a) => Double -> a?

The question is, what semantics do you want from it? Semantics is not always determined by the type, even in Haskell.

An example of such function (even without Ord a constraint) is:

doubleToNum = fromInteger . round

It satisfies the type you want, but e.g. it will not give you identity if you apply it to get Double.

Roman Cheplyaka
I suppose I want the identity. Maybe I'm thinking about the types all wrong?
qrest
+1  A: 

You won't be able to find very many interesting functions that can convert a Double into any instance of Ord and Num. You can create some pretty wild types that satisfy those two constraints.

Without knowing anything else, the only way you can construct values out of thin air is using fromInteger. And the Ord instance isn't going to help you, as far as I can see.

So you could do something like:

f :: (Ord a, Num a) => Double -> a
f = fromInteger . floor

Or even more trivially, f = const 0. :) But there's not much you can do with the fractional part of your Doubles, because there is no guarantee that your target type has anything fractional about it.

Perhaps you are looking for Fractional a => Double -> a? Then you could use realToFrac.

Yitz
Maybe what you want to do is truncate (or round) when the target type is not fractional, but keep the fractional part if the target type supports that. If so, then you'll need to make the target type part of what varies in your class, using an extension like "multi-parameter type classes" or "associated types". Or just treat those two cases separately, each with its own class.
Yitz
+1  A: 

STOP!

Take a deep breath, and write out what it is that you "really" want.

I am going to stop trying to guess something that you'll like, and ask for another rephrasal. I think realToFrac may do what you're looking for, but I'm not sure.

Are you looking for a function that takes a Double and, somehow "invents" a new type that is a member of Ord and Num, but with no more specified behavior? Do you want a way to use a Double with some other type that you already have in mind?

Just as a small "thought experiment", imagine the computer tries to use your function on a Bool - could you phrase the question in such a way that it makes sense somehow on a Bool, or it clearly could not work with a Bool?

I'm sorry I couldn't answer your question as asked, but hoping that I've helped you to somehow get a better answer.

BMeph