简体   繁体   中英

Implementing a type class using a GADT

I have written the following linear algebra vector in Haskell

data Natural where
    Zero :: Natural
    Succ :: Natural -> Natural

data Vector n e where
    Nil :: Vector Zero e
    (:|) :: (Show e, Num e) => e -> Vector n e -> Vector (Succ n) e
infixr :|

instance Foldable -- ... Vector ..., but how do I implement this?

When I try to implement Foldable , I run into the problem that Zero and Succ have different definitions (ie. * and * -> *).

Is there an obvious solution to this problem?

It's just

instance Foldable (Vector n) where
  fold Nil       = mempty
  fold (a :| as) = a <> fold as

I would not recommend adding constraints to the e type, though.

You don't need to mention Zero or Succ in the class instance, that is the entire point of a GADT: pattern matching on the constructor gives you type information:

instance F.Foldable (Vector v) where
  foldr _ zero Nil = zero
  foldr f zero (e0 :| v) = f e0 $ F.foldr f zero v 

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM