[Haskell-cafe] View patterns

Simon Peyton-Jones simonpj at microsoft.com
Mon Mar 1 03:59:50 EST 2010


| However, as somebody pointed out, the Java version is polymorphic.
| Assuming that length() is defined for multiple types of container, the
| Java version works with lists, arrays, sets, etc. If you try to do this
| in Haskell, you end up with

A standard way to do it would be this:

class ListLike c where
  lcase :: c a -> LCase a (c a)
  lcons :: a -> c a -> c a
  lnil  :: c a

data LCase a b = LNil | LCons a b

f :: ListLike c => c (c Int) -> Int
f (lcase -> LCons (lcase -> LCons x (lcase -> LNil))
     (lcase -> LCons (lcase -> LCons y (lcase -> LCons _ (lcase -> LNil)))
        (lcase -> LNil))) 
  = x+y


Simon

| -----Original Message-----
| From: haskell-cafe-bounces at haskell.org [mailto:haskell-cafe-bounces at haskell.org] On
| Behalf Of Andrew Coppin
| Sent: 27 February 2010 18:11
| To: haskell-cafe at haskell.org
| Subject: [Haskell-cafe] View patterns
| 
| One somewhat neat thing about Haskell is that you can say
| 
|   case list of
|     [[x], [y,_], [z,_,_]] -> x + y + z
|     _ -> 0
| 
| In Java, you'd have to write something like
| 
|   if (list.length() == 3)
|   {
|     List t1 = list.at(0);
|     if (t1.length() == 1)
|     {
|       int x = t1.at(0);
|       List t2 = list.at(1);
|       if (t2.length() == 2)
|       ...
| 
| I can't even be bothered to finish typing all that lot!
| 
| However, as somebody pointed out, the Java version is polymorphic.
| Assuming that length() is defined for multiple types of container, the
| Java version works with lists, arrays, sets, etc. If you try to do this
| in Haskell, you end up with
| 
|   case size c of
|     3 ->
|       case (c ! 0, c ! 1, c ! 2) of
|         (xs, ys, zs) | size x == 1 && size y == 2 & size z == 3 -> (xs !
| 0) + (ys ! 0) + (zs ! 0)
|         _ -> 0
|     _ -> 0
| 
| or similar. Which is shorter than Java, but nowhere near as nice as the
| original list-only version.
| 
| Now I was under the impression that "view patterns" fix this problem,
| but it seems they don't:
| 
|   case c of
|     (size -> 3) ->
|       case (c ! 0, c ! 1, c ! 2) of
|         (size -> 1, size -> 2, size -> 3) -> (c ! 0 ! 0) + (c ! 1 ! 0) +
| (c ! 2 ! 0)
| 
| Any suggestions?
| 
| _______________________________________________
| Haskell-Cafe mailing list
| Haskell-Cafe at haskell.org
| http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list