[Haskell-beginners] Here's why functions should return functions

Ertugrul Söylemez es at ertes.de
Sun Jul 29 14:42:18 CEST 2012


"Costello, Roger L." <costello at mitre.org> wrote:

> Recently I had a small epiphany: when creating functions, design them
> to return functions rather than non-function values (Integer, Bool,
> list, tuple, etc.).
>
> Here's why:
>
> Consider a function that returns, say, the integer four ( 4 ). The
> type of the value returned by the function is this:
>
> 4 :: Num a => a

This is not a Haskell function (even though it does actually compile to
a function, unless you use specialization).  If it doesn't involve the
(->) type constructor, then it's not a function.


> That is, the value returned is not a function, it is a number.

If you were to say x = 4, then 'x' is not a function.  It's a value
equal to 4.  The equality sign in Haskell is not an assignment and
doesn't introduce a function definition.  It introduces an equation, so
"x = y" means that x is /the same/ as y.


> However, there are advantages to returning a function rather than a
> number.
>
> Recall the composition operator ( . )
>
> [...]

There is a design pattern, where you compose functions ((->)) or
function-like objects (Category/Arrow).  In this design pattern you work
with constant functions to introduce values.  This is used in FRP, for
example:

    integral 0 . pure 4

This is the integral of the constant 4 with respect to time.


> Here's a data type that lifts non-function values to functions:
>
> [...]

No, it doesn't.


> data Lift a = Function a
>                     deriving (Show)

You have just reinvented an awkward version (data instead of newtype) of
the identity functor, which is both a monad (a -> Identity a) and a
comonad (Identity a -> a).  I don't see what it buys you given 'const'.

Haskell is a language to study new ways of thinking, so it's great that
you think, but you should really first learn the language properly.  You
will find it helpful to learn the various type classes for categorical
programming, in particular Category, Applicative and Arrow.  There is
the reader monad, in which you would write the following:

    fmap (^2) . fmap succ . pure 4

or equivalently:

    fmap ((^2) . succ) . pure 4

The reader monad is defined as:

    instance Applicative (e ->)
    instance Functor (e ->)
    instance Monad (e ->)

Since (->) forms a category, you have composition and an identity
morphism (the identity function).

In other words, you have just invented an awkward way to write what can
already be written nicely using existing stuff.


Greets,
Ertugrul

-- 
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20120729/f090b8a1/attachment.pgp>


More information about the Beginners mailing list