Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write length function for list with statically typed length

Tags:

types

haskell

Given a list with a statically typed length (taking this as an example):

data Zero

data Succ nat

data List el len where
    Nil  ::                      List el Zero
    Cons :: el -> List el len -> List el (Succ len)

is it possible to write a length function that calculates the length using the static typing rather than the usual recursion?

My efforts thus far have led me to the conclusion that it is not possible, as it would require "unlifting" the type information in order to recur on it:

class HasLength a where
    length :: a -> Natural

instance HasLength (List el Zero) where
    length _ = 0

instance HasLength (List el (Succ len)) where
    length _ = 1 + *how to recur on type of len*

However, I am only just beginning to learn about all the magic possible with types, so I know that my not being able to conceive of a solution does not imply the absence of one.

update

Since length returns Natural, I incorrectly wrote length _ = 1 + .... The correct instance (using the answer given below) is

instance HasLength (List el len) => HasLength (List el (Succ len)) where
    length _ = succ $ length (undefined :: List el len)
like image 475
lukerandall Avatar asked Nov 25 '12 22:11

lukerandall


1 Answers

For example like this:

instance HasLength (List el len) => HasLength (List el (Succ len)) where
    length _ = 1 + length (undefined :: List el len)

Note: this requires ScopedTypeVariables extension.

like image 135
Ed'ka Avatar answered Nov 15 '22 07:11

Ed'ka