2

In the source code for Data.FixedList, I found the following definition:

data FixedList f =>
  Cons f a = (:.) {
    head :: a,
    tail :: (f a)
  }  deriving (Eq, Ord)

As someone very new to Haskell, it's hard to figure out what's going on here. I understand syntax such as data TypeName = TypeName { a :: Int, b :: Int} deriving (Show) or data TypeName = TypeA | TypeB, but the code above is over my head. Any documentation / or walk-through would be much appreciated!

sinθ
  • 11,093
  • 25
  • 85
  • 121

2 Answers2

7

First of all the FixedList f => enforces the constraint that f is a FixedList when using the constructor. I'm not sure why it's used here. It is generally advised against.

In Haskell, you can make infix data constructors with symbols starting with :. In the library, the constructor is put in brackets (:.) so it can be used with record syntax. Without record syntax it would look like this:

data Cons f a = a :. f a

Pattern matching is very similar to lists. Here's a simple function using it:

mapHead :: FixedList f => (a -> a) -> Cons f a -> Cons f a
mapHead f (a :. as) = f a :. as

Here's a definition without using an infix constructor.

data Cons f a = Cons
  { head :: a
  , tail :: f a
  }
Community
  • 1
  • 1
cchalmers
  • 2,896
  • 1
  • 11
  • 11
4

This is mostly fancy formatting of things you've seen before.

data FixedList f => Cons f a = (:.) { head :: a
                                    , tail :: (f a)
                                    } deriving (Eq, Ord)

FixedList f is just a typeclass constraint on the Cons f a datatype. (:.) is an infix data constructor.

R B
  • 1,109
  • 9
  • 13