does this irritate anyone else?

Hal Daume III hdaume@ISI.EDU
Wed, 26 Feb 2003 08:50:48 -0800 (PST)


One way to get around this is to do something like:

> newtype DetectiveLocations = DetectiveLocations SomeType1
> newtype FugitiveLocations  = FugitiveLocations SomeType2
>
> class MkUn nt t | nt -> t where
>    mk :: t -> nt
>    un :: nt -> t
>
> instance MkUn DetectiveLocations SomeType1 where
>    mk = DetectiveLocations
>    un (DetectiveLocations dl) = dl
>
> -- similarly for FugLocs

Then, your function is a bit cleaner with (note that the type sig is very
important now):

> findFugitive dL fL StartGame = 
>     mk (minusSet (un dL) (occupiedStops (un fL))

Another way to do it would be if 'minusSet' were a class method, then you
could use GHC's newtype deriving feature (or in Hugs just define the
obvious instances).  For instance, if we had:

> class Set s where
>    minusSet :: Set a -> Set a -> Set a
>    ...

then you could do:

> newtype DetectiveLocations = DetectiveLocations SomeType1
>     deriving (Set)
> newtype FugitiveLocations  = FugitiveLocations SomeType2
>     deriving (Set)

assuming SomeType1 and SomeType2 were instances of Set; then your second
definition would be fine.

Finally, if you make your constructor names shorter, it doesn't look quite
so bad and you get nice error messages and helpful type checking.

As for why you get ambiguous variables, I'd need to see the offending data
and instance definitions.

HTH

 - Hal

--
Hal Daume III

 "Computer science is no more about computers    | hdaume@isi.edu
  than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume

On Wed, 26 Feb 2003, Mike T. Machenry wrote:

> I am trying to use type classes to get some percollate actions through a
> nested data structure. The problem is I can't make an instance of a class
> unless the type is defined with newtype or data. This means all of my
> functions look something like this:
> 
> findFugitive :: DetectiveLocations -> FugitiveLocations -> Move -> FugitiveLocat
> findFugitive (DetectiveLocations dL) (FugitiveLocations fL) StartGame =
>   (FugitiveLocations minusSet fL (occupiedStops dL))
> 
> instead of this:
> 
> findFugitive :: DetectiveLocations -> FugitiveLocations -> Move -> FugitiveLocat
> findFugitive dL fL StartGame = minusSet fL (occupiedStops dL)
> 
> which is much simpler to read. Why can't I make a normal type an instance of 
> a type class? I get errors that it's an ambiguous type.
> 
> thanks,
> -mike
> _______________________________________________
> Haskell mailing list
> Haskell@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
>