david48 | 20 Dec 16:45

Class/Instance : what am I doing wrong in this example ?

I'm really inexperienced at this :

-----------
{-# OPTIONS_GHC -fglasgow-exts -funbox-strict-fields
-fallow-undecidable-instances -O2 #-}

class Gadget g where
  fInit  :: g -> a -> g

data FString = FString !Int !String deriving Show

instance Gadget FString where
  fInit (FString n _) s = FString n (take n s)

-------------

I get the error message :
     Couldn't match expected type `String' against inferred type `a'
      `a' is a rigid type variable bound by
    the type signature for `fInit' at Gadget.hs:4:17
    In the second argument of `FString', namely `s'
    In the expression: FString n s
    In the definition of `fInit': fInit (FString n _) s = FString n s
Claude Heiland-Allen | 20 Dec 17:03

Re: Class/Instance : what am I doing wrong in this example ?

david48 wrote:
| I'm really inexperienced at this :

> class Gadget g where
>   fInit  :: g -> a -> g
> 
> data FString = FString !Int !String deriving Show
> 
> instance Gadget FString where
>   fInit (FString n _) s = FString n (take n s)

The types of:

 > fInit :: g -> a -> g

and:

 > take :: Int -> [a] -> [a]

cause the mismatched types error.

You're trying to apply 'take n' to a value of type 'a' ('take n' 
requires [a]), moreover putting the value of 'take n s' into the FString 
further constrains its type to be [Char] == String.

So either fix the Gadget g class, or fix the Gadget FString instance.

Claude
--

-- 
http://claudiusmaximus.goto10.org
(Continue reading)

david48 | 20 Dec 17:10

Re: Class/Instance : what am I doing wrong in this example ?

On Dec 20, 2007 5:03 PM, Claude Heiland-Allen
<claudiusmaximus <at> goto10.org> wrote:

> You're trying to apply 'take n' to a value of type 'a' ('take n'
> requires [a]), moreover putting the value of 'take n s' into the FString
> further constrains its type to be [Char] == String.

First of all, thanks a lot for your reply.

I thought that in this case my type a was String ( which I know is [Char] )
since I give fInit a value of type g ( FString n _ ) and a value of type a ( s )
and I return a value of type g ( FString n (take n s) )

David
Tillmann Rendel | 20 Dec 17:26

Re: Class/Instance : what am I doing wrong in this example ?

david48 wrote:
> class Gadget g where
>   fInit  :: g -> a -> g
> 
> data FString = FString !Int !String deriving Show
> 
> instance Gadget FString where

at this point fInit has this type:

   FString -> a -> FString

>   fInit (FString n _) s = FString n (take n s)

but your implementation has this type

   FString -> String -> FString

These types are incompatible, your fInit implementation should be able 
to work with whatever type a the caller has choosen to provide. Maybe 
you should try one of

   class Gadget g where
     fInit  :: g -> String -> g

or

   class Gadget g a where
     fInit  :: g -> a -> g

(Continue reading)

Jules Bean | 20 Dec 17:36

Re: Class/Instance : what am I doing wrong in this example ?

Tillmann Rendel wrote:
> david48 wrote:
>> class Gadget g where
>>   fInit  :: g -> a -> g

Tillman's two suggestions (below) are probably your answer.

Just to say what everyone else has said in a bunch of different ways: 
your class says that for ANY Gadget, fInit will work with ANY OTHER type a.

This doesn't seem to be what you want. There are three things you might 
want:

1. Maybe you want a to always be String. Easy. fInit :: g -> String -> g

2. Maybe you want lots of possible different "a"s for each "g". Then you 
make "a" a parameter of the class too.

3. Maybe you want just one particular "a" for each "g". I.e. "g" 
determines "a". Then you can proceed as for (2), but add the functional 
dependency | g -> a

> These types are incompatible, your fInit implementation should be able 
> to work with whatever type a the caller has choosen to provide. Maybe 
> you should try one of
> 
>   class Gadget g where
>     fInit  :: g -> String -> g
> 
> or
(Continue reading)

david48 | 20 Dec 17:53

Re: Class/Instance : what am I doing wrong in this example ?

On Dec 20, 2007 5:36 PM, Jules Bean <jules <at> jellybean.co.uk> wrote:
> 2. Maybe you want lots of possible different "a"s for each "g". Then you
> make "a" a parameter of the class too.

> 3. Maybe you want just one particular "a" for each "g". I.e. "g"
> determines "a". Then you can proceed as for (2), but add the functional
> dependency | g -> a

Practically, what would be the difference between 2. and 3. ?

David.
david48 | 20 Dec 17:44

Re: Class/Instance : what am I doing wrong in this example ?

On Dec 20, 2007 5:26 PM, Tillmann Rendel
<rendel <at> rbg.informatik.tu-darmstadt.de> wrote:

> at this point fInit has this type:
>    FString -> a -> FString
> >   fInit (FString n _) s = FString n (take n s)
> but your implementation has this type
>    FString -> String -> FString
> These types are incompatible, your fInit implementation should be able
> to work with whatever type a the caller has choosen to provide. Maybe

That was a very clear explanation of what's wrong, thanks a lot !

> you should try one of

>    class Gadget g where
>      fInit  :: g -> String -> g

This will not do, I want instances of gadget that work with other
values than string.

> or
>    class Gadget g a where
>      fInit  :: g -> a -> g

A bit of explanation.

I want types of class "Gadget" to be able to hold values of some type.
for example, some of the types in the class Gadget would hold strings,
some would hold Integers.
(Continue reading)

david48 | 20 Dec 17:48

Re: Class/Instance : what am I doing wrong in this example ?

On Dec 20, 2007 5:44 PM, david48 <dav.vire+haskell <at> gmail.com> wrote:
> fString :: Int -> FString
> fString n = FString n ""

Oooooo do I feel dumb for writing this !

Problem solved :)

Gmane