[Haskell-cafe] Smart Constructor Puzzle
Henning Thielemann
lemming at henning-thielemann.de
Fri Dec 21 06:14:34 EST 2007
On Thu, 20 Dec 2007, Stefan O'Rear wrote:
> On Thu, Dec 20, 2007 at 11:39:42PM -0500, Ronald Guida wrote:
> > > data PZero = PZero deriving (Show)
> > > data PSucc a = PSucc a deriving (Show)
> > >
> > > type P1 = PSucc PZero
> > > type P2 = PSucc P1
> > > type P3 = PSucc P2
> > > -- etc
>
> ...
>
> > Now here's the puzzle. I want to create a function "vecLength" that
> > accepts a vector and returns its length. The catch is that I want to
> > calculate the length based on the /type/ of the vector, without
> > looking at the number of elements in the list.
> >
> > So I started by defining a class that allows me to convert a Peano
> > number to an integer. I couldn't figure out how to define a function
> > that converts the type directly to an integer, so I am using a
> > two-step process. Given a Peano type /t/, I would use the expression
> > "pToInt (pGetValue :: t)".
> >
> > > class Peano t where
> > > pGetValue :: t
> > > pToInt :: t -> Int
> > >
> > > instance Peano PZero where
> > > pGetValue = PZero
> > > pToInt _ = 0
> > >
> > > instance (Peano t) => Peano (PSucc t) where
> > > pGetValue = PSucc pGetValue
> > > pToInt (PSucc a) = 1 + pToInt a
Why the two methods pGetValue and pToInt? I thought that pGetValue should
have signature pGetValue :: t -> Peano and that pToInt can convert the
result from pGetValue to Int.
> > Finally, I tried to define vecLength, but I am getting an error.
> >
> > > vecLength :: (Peano s) => Vec s t -> Int
> > > vecLength _ = pToInt (pGetValue :: s)
>
> 1. pGetValue is unneccessary, undefined :: s will work just as well.
> This is a fairly standard approach; the precision values in Floating,
> bitSize :: Bits a => a -> Int, and sizeOf :: Storable a => a -> Int
> all work this way.
What about functions of type
bitSize :: Bits a => (a, Int)
This would also make explicit, that you don't have to provide a value of
type 'a'.
'sizeOf' might still return different size depending on the value, right?
E.g. when converting a sum data type to a (C++) object.
More information about the Haskell-Cafe
mailing list