I'm trying to create a class Func
which represents a function, and then a data type Dot
which composes functions. Below is my attempt, but I'm getting compile errors:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE GADTs #-}
module Func where
class Func f a b | f -> a, f -> b where
apply :: f -> a -> b
data Dot f1 f2 where
Dot :: (Func f1 a b, Func f2 b c) => f1 -> f2 -> Dot f1 f2
instance Func (Dot f1 f2) a c where
apply (Dot f1 f2) = (apply f2) . (apply f1)
I get the following errors:
Func.hs:15:26:
Could not deduce (Func f2 b c) arising from a use of `apply'
from the context (Func f1 a1 b, Func f2 b c1)
bound by a pattern with constructor
Dot :: forall f1 f2 a b c.
(Func f1 a b, Func f2 b c) =>
f1 -> f2 -> Dot f1 f2,
in an equation for `apply'
at Func.hs:15:12-20
Possible fix:
add (Func f2 b c) to the context of
the data constructor `Dot'
or the instance declaration
In the first argument of `(.)', namely `(apply f2)'
In the expression: (apply f2) . (apply f1)
In an equation for `apply':
apply (Dot f1 f2) = (apply f2) . (apply f1)
Func.hs:15:39:
Could not deduce (Func f1 a b) arising from a use of `apply'
from the context (Func f1 a1 b, Func f2 b c1)
bound by a pattern with constructor
Dot :: forall f1 f2 a b c.
(Func f1 a b, Func f2 b c) =>
f1 -> f2 -> Dot f1 f2,
in an equation for `apply'
at Func.hs:15:12-20
Possible fix:
add (Func f1 a b) to the context of
the data constructor `Dot'
or the instance declaration
In the second argument of `(.)', namely `(apply f1)'
In the expression: (apply f2) . (apply f1)
In an equation for `apply':
apply (Dot f1 f2) = (apply f2) . (apply f1)
What do I need to fix to make this compile?
I realise this might seem a bit silly, but I thought it might be useful to be able to carry around different functions as unique types, as one could perhaps attach various metadata to those types (I'm not sure exactly what yet).