Explain how does new foldr work in Haskell - haskell

New Haskell programmer will soon enough go to sources to see how foldr is implemented. Well, the code used to be simple (don't expect newcomers to know about OldList or FTP).
How does the new code work?
-- | Map each element of the structure to a monoid,
-- and combine the results.
foldMap :: Monoid m => (a -> m) -> t a -> m
foldMap f = foldr (mappend . f) mempty
-- | Right-associative fold of a structure.
--
-- #'foldr' f z = 'Prelude.foldr' f z . 'toList'#
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo #. f) t) z

I'll just mention the parts that are not in the answer #duplode linked.
First, those implementations you list are default methods. Every Foldable type needs to provide its own specific version of at least one of them, and lists ([]) provide foldr, which is implemented pretty much as it always has been:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
(Which is, for efficiency, a bit different from the Haskell report version.)
Also, a slight change in the Foldable default since duplode's answer is that strange #. operator, used internally in GHC's Data.Foldable code. It's basically a more efficient version of . that works only when the left function is a newtype wrapper/unwrapper function. It's defined using the new newtype coercion mechanism, and gets optimized into essentially nothing:
(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)
(#.) _f = coerce
{-# INLINE (#.) #-}

The mental model I have for foldr follows this structure:
Given a list in it's a:(b:(c:[])) form, replace all ":" with the given
op (1st parameter), and then replace the "[]" with the given initial
value (2nd parameter).
A pseudo-codey example:
foldr (+) 0 [1,2,3,4] = 1 + 2 + 3 + 4 + 0
And remember, [1,2,3,4] is equivalent to 1:(2:(3:(4:[])))

Related

Cartesian product set generation [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
I am trying to create a Haskell function to generate a Cartesian product of two lists
Here's my attempt:
cartesianProduct :: (a -> b -> c) -> [a] -> [b] -> [c]
cartesianProduct f x [] = x
cartesianProduct f y [] = y
cartesianProduct = f x y unionHelper func1 f xs ys
If you're in a hurry, then the function is called liftA2 and it's actually built-in.
sort $ liftA2 (*) [1,2,4] [1,3,9] -- [1,2,3,4,6,9,12,18,36]
But, of course, that's not very enlightening, so let's talk about how we might do it ourselves.
The list type, [], is a functor. We can implement fmap directly using recursion.
fmap :: (a -> b) -> [a] -> [b]
fmap _ [] = []
fmap f (x:xs) = f x : fmap f xs
Now we have a way of to do something for each element of a list. Great, that's how we'll apply our final operation, but we need to generate all of the argument lists as well. Specifically, we want to produce the Cartesian product.
cross :: [a] -> [b] -> [(a, b)]
And we can do so recursively as well, using our fmap function to help out.
cross :: [a] -> [b] -> [(a, b)]
cross [] _ = []
cross (x:xs) ys = fmap ((,) x) ys ++ cross xs ys
Recursion on the first element. If the first argument is empty, then the Cartesian product is empty. If the first argument is nonempty, then the result should consist of the head paired with each (via fmap) element of the second argument, followed by the Cartesian product of the tail with the second list.
Now we have a way to get a [(Int, Int)]. And we want to multiply those elements, so it's just a matter of tying it all together.
apply2 :: (a -> b -> c) -> [a] -> [b] -> [c]
apply2 f xs ys = fmap (\(x, y) -> f x y) $ cross xs ys
Take the Cartesian product of the two lists, then apply our function f (uncurried) to each element.
This gives us our result, in a slightly different order than in your example. But it looks like you're sorting the results anyway, rather than producing them in an algorithmic order.
sort $ apply2 (*) [1,2,4] [1,3,9] -- [1,2,3,4,6,9,12,18,36]
Now, let's talk about why liftA2 works. The list type is an example of an applicative functor, represented by the Applicative typeclass. Whereas fmap (which is part of Functor) takes a single function and maps it over a functor (in our case, over several elements of a list), the fundamental applicative operation is <*> (pronounced "ap"), whose signature is
fmap :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Instead of mapping a single simple function over a functor value f a, we're mapping a function inside the functor f (a -> b) over a value also inside the functor f a. Now, this is a jumble of words, but in the case of lists it looks like
fmap :: (a -> b) -> [a] -> [b]
(<*>) :: [a -> b] -> [a] -> [b]
Rather than applying a single function to several elements, we're applying several functions to several elements. (<*>) is actually just our cross function written in a slightly different way. It's combining two lists using every combination to produce a result of some type. (In fact, the relationship between our cross and the applicative (<*>) is rather deep mathematically, due to the fact that (->) and (,) are adjoint to each other, but that's getting off track)
So (<*>) is just cross by another name. And liftA2 is defined as (something equivalent to)
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = fmap f a <*> b
It's just doing fmap and (<*>), which is basically what our apply2 function was doing to begin with. Again, it's slightly shuffled around since we're using (->) rather than (,) (since our "ap" operator applies a function rather than building a tuple), but it's exactly the same idea.
Certainly, the liftA2 approach is snazzy and short, but don't let it blind you. There's nothing wrong with a recursive approach, especially as you're learning. If apply2 makes more sense to you and my explanation above of the applicative functors was nonsense, then go for it. You can go a long way in Haskell learning about recursion and data structures before really grokking functors, and that's fine. But when you're ready, I recommend Typeclassopedia for an excellent summary of the Haskell typeclasses that represent functors, applicative functors, monads, and all of the other lesser-known abstractions available to the programmer.
Good luck, and happy coding!

How to create a function that takes a list of arguments and returns a function that applies arguments to another function [duplicate]

Shouldn’t this definition be allowed in a lazy language like Haskell in which functions are curried?
apply f [] = f
apply f (x:xs) = apply (f x) xs
It’s basically a function that applies the given function to the given list of arguments and is very easily done in Lisp for example.
Are there any workarounds?
It is hard to give a static type to the apply function, since its type depends on the type of the (possibly heterogeneous) list argument. There are at least two ways one way to write this function in Haskell that I can think of:
Using reflection
We can defer type checking of the application until runtime:
import Data.Dynamic
import Data.Typeable
apply :: Dynamic -> [Dynamic] -> Dynamic
apply f [] = f
apply f (x:xs) = apply (f `dynApp` x) xs
Note that now the Haskell program may fail with a type error at runtime.
Via type class recursion
Using the semi-standard Text.Printf trick (invented by augustss, IIRC), a solution can be coded up in this style (exercise). It may not be very useful though, and still requires some trick to hide the types in the list.
Edit: I couldn't come up with a way to write this, without using dynamic types or hlists/existentials. Would love to see an example
I like Sjoerd Visscher's reply, but the extensions -- especially IncoherentInstances, used in this case to make partial application possible -- might be a bit daunting. Here's a solution that doesn't require any extensions.
First, we define a datatype of functions that know what to do with any number of arguments. You should read a here as being the "argument type", and b as being the "return type".
data ListF a b = Cons b (ListF a (a -> b))
Then we can write some (Haskell) functions that munge these (variadic) functions. I use the F suffix for any functions that happen to be in the Prelude.
headF :: ListF a b -> b
headF (Cons b _) = b
mapF :: (b -> c) -> ListF a b -> ListF a c
mapF f (Cons v fs) = Cons (f v) (mapF (f.) fs)
partialApply :: ListF a b -> [a] -> ListF a b
partialApply fs [] = fs
partialApply (Cons f fs) (x:xs) = partialApply (mapF ($x) fs) xs
apply :: ListF a b -> [a] -> b
apply f xs = headF (partialApply f xs)
For example, the sum function could be thought of as a variadic function:
sumF :: Num a => ListF a a
sumF = Cons 0 (mapF (+) sumF)
sumExample = apply sumF [3, 4, 5]
However, we also want to be able to deal with normal functions, which don't necessarily know what to do with any number of arguments. So, what to do? Well, like Lisp, we can throw an exception at runtime. Below, we'll use f as a simple example of a non-variadic function.
f True True True = 32
f True True False = 67
f _ _ _ = 9
tooMany = error "too many arguments"
tooFew = error "too few arguments"
lift0 v = Cons v tooMany
lift1 f = Cons tooFew (lift0 f)
lift2 f = Cons tooFew (lift1 f)
lift3 f = Cons tooFew (lift2 f)
fF1 = lift3 f
fExample1 = apply fF1 [True, True, True]
fExample2 = apply fF1 [True, False]
fExample3 = apply (partialApply fF1 [True, False]) [False]
Of course, if you don't like the boilerplate of defining lift0, lift1, lift2, lift3, etc. separately, then you need to enable some extensions. But you can get quite far without them!
Here is how you can generalize to a single lift function. First, we define some standard type-level numbers:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, TypeFamilies, UndecidableInstances #-}
data Z = Z
newtype S n = S n
Then introduce the typeclass for lifting. You should read the type I n a b as "n copies of a as arguments, then a return type of b".
class Lift n a b where
type I n a b :: *
lift :: n -> I n a b -> ListF a b
instance Lift Z a b where
type I Z a b = b
lift _ b = Cons b tooMany
instance (Lift n a (a -> b), I n a (a -> b) ~ (a -> I n a b)) => Lift (S n) a b where
type I (S n) a b = a -> I n a b
lift (S n) f = Cons tooFew (lift n f)
And here's the examples using f from before, rewritten using the generalized lift:
fF2 = lift (S (S (S Z))) f
fExample4 = apply fF2 [True, True, True]
fExample5 = apply fF2 [True, False]
fExample6 = apply (partialApply fF2 [True, False]) [False]
No, it cannot. f and f x are different types. Due to the statically typed nature of haskell, it can't take any function. It has to take a specific type of function.
Suppose f is passed in with type a -> b -> c. Then f x has type b -> c. But a -> b -> c must have the same type as a -> b. Hence a function of type a -> (b -> c) must be a function of type a -> b. So b must be the same as b -> c, which is an infinite type b -> b -> b -> ... -> c. It cannot exist. (continue to substitute b -> c for b)
Here's one way to do it in GHC. You'll need some type annotations here and there to convince GHC that it's all going to work out.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE IncoherentInstances #-}
class Apply f a r | f -> a r where
apply :: f -> [a] -> r
instance Apply f a r => Apply (a -> f) a r where
apply f (a:as) = apply (f a) as
instance Apply r a r where
apply r _ = r
test = apply ((+) :: Int -> Int -> Int) [1::Int,2]
apply' :: (a -> a -> a) -> [a] -> a
apply' = apply
test' = apply' (+) [1,2]
This code is a good illustration of the differences between static and dynamic type-checking. With static type-checking, the compiler can't be sure that apply f really is being passed arguments that f expects, so it rejects the program. In lisp, the checking is done at runtime and the program might fail then.
I am not sure how much this would be helpful as I am writing this in F# but I think this can be easily done in Haskell too:
type 'a RecFunction = RecFunction of ('a -> 'a RecFunction)
let rec apply (f: 'a RecFunction) (lst: 'a list) =
match (lst,f) with
| ([],_) -> f
| ((x::xs), RecFunction z) -> apply (z x) xs
In this case the "f" in question is defined using a discriminated union which allows recursive data type definition. This can be used to solved the mentioned problem I guess.
With the help and input of some others I defined a way to achieve this (well, sort of, with a custom list type) which is a bit different from the previous answers. This is an old question, but it seems to still be visited so I will add the approach for completeness.
We use one extension (GADTs), with a list type a bit similar to Daniel Wagner's, but with a tagging function type rather than a Peano number. Let's go through the code in pieces. First we set the extension and define the list type. The datatype is polymorphic so in this formulation arguments don't have to have the same type.
{-# LANGUAGE GADTs #-}
-- n represents function type, o represents output type
data LApp n o where
-- no arguments applied (function and output type are the same)
End :: LApp o o
-- intentional similarity to ($)
(:$) :: a -> LApp m o -> LApp (a -> m) o
infixr 5 :$ -- same as :
Let's define a function that can take a list like this and apply it to a function. There is some type trickery here: the function has type n, a call to listApply will only compile if this type matches the n tag on our list type. By leaving our output type o unspecified, we leave some freedom in this (when creating the list we don't have to immediately entirely fix the kind of function it can be applied to).
-- the apply function
listApply :: n -> LApp n o -> o
listApply fun End = fun
listApply fun (p :$ l) = listApply (fun p) l
That's it! We can now apply functions to arguments stored in our list type. Expected more? :)
-- showing off the power of AppL
main = do print . listApply reverse $ "yrruC .B lleksaH" :$ End
print . listApply (*) $ 1/2 :$ pi :$ End
print . listApply ($) $ head :$ [1..] :$ End
print $ listApply True End
Unfortunately we are kind of locked in to our list type, we can't just convert normal lists to use them with listApply. I suspect this is a fundamental issue with the type checker (types end up depending on the value of a list) but to be honest I'm not entirely sure.
-- Can't do this :(
-- listApply (**) $ foldr (:$) End [2, 32]
If you feel uncomfortable about using a heterogeneous list, all you have to do is add an extra parameter to the LApp type, e.g:
-- Alternative definition
-- data FList n o a where
-- Nil :: FList o o a
-- Cons :: a -> FList f o a -> FList (a -> f) o a
Here a represents the argument type, where the function which is applied to will also have to accept arguments of all the same type.
This isn't precisely an answer to your original question, but I think it might be an answer to your use-case.
pure f <*> [arg] <*> [arg2] ...
-- example
λ>pure (\a b c -> (a*b)+c) <*> [2,4] <*> [3] <*> [1]
[7,13]
λ>pure (+) <*> [1] <*> [2]
[3]
The applicative instance of list is a lot broader than this super narrow use-case though...
λ>pure (+1) <*> [1..10]
[2,3,4,5,6,7,8,9,10,11]
-- Or, apply (+1) to items 1 through 10 and collect the results in a list
λ>pure (+) <*> [1..5] <*> [1..5]
[2,3,4,5,6,3,4,5,6,7,4,5,6,7,8,5,6,7,8,9,6,7,8,9,10]
{- The applicative instance of list gives you every possible combination of
elements from the lists provided, so that is every possible sum of pairs
between one and five -}
λ>pure (\a b c -> (a*b)+c) <*> [2,4] <*> [4,3] <*> [1]
[9,7,17,13]
{- that's - 2*4+1, 2*3+1, 4*4+1, 4*3+1
Or, I am repeating argC when I call this function twice, but a and b are
different -}
λ>pure (\a b c -> show (a*b) ++ c) <*> [1,2] <*> [3,4] <*> [" look mah, other types"]
["3 look mah, other types","4 look mah, other types","6 look mah, other types","8 look mah, other types"]
So it's not the same concept, precisely, but it a lot of those compositional use-cases, and adds a few more.

Folding a list of functions?

I am trying to combine an arbitrary number of mathematical functions that are in a list.
I've written a compose function that chains them together:
chain :: (c -> d) -> (a -> b -> c) -> a -> b -> d
g `chain` f = \a b -> g (f a b)
So doing something like
let b = (*) `chain` (+) `chain` (-)
Creates a function that takes a b c d, and does ((a − b) + c) × d
> b 2 3 4 5
> 15
My question is, I want to be able to chain a set of these together based on an arbitrary list:
[(*),(+),(-)] would result in (*) `chain` (+) `chain` (-)
[(*),(+),(-),(*)] would result in (*) `chain` (+) `chain` (-) `chain` (*)
Is this possible? I've tried using folds but cannot get it to work since the type of the accumulator changes after each application of an element.
For example, the type of three functions chained together is:
b :: Integer -> Integer -> Integer -> Integer -> Integer
But for four it is:
b :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer
If someone could point me in the right direction or knows of a solution, that would be great! Thank you.
EDIT:
My end goal is to be able to do something like this:
getZipList $ pure (function composing * and +) <*> ZipList [1,2,3] <*> ZipList [4,5,6]
<*> ZipList [7,8,9]
would result in:
[(1+4)*7, (2+5)*8, (3+6)*9]
Well, as you note yourself it can't really be possible, since different lists lengths (invisible to the type system) would result in different types. The only "solid" way do do it would be some kind of compile-time list; there are various around but none of them is really stably supported and easy to use.
The easiest alternative would be to also take the arguments as a list. i.e.,
ifxChain :: [a->a->a] -> [a] -> a
That one could easily be implemented: it's basically a zip to supply the second argument to each function, ommiting the first one. Then you fold that first parameter through the resulting list of single-parameter functions:
ifxChain fs (p0:ps) = foldl' (flip ($)) p0 $ zipWith flip fs ps
You may want to add handling of lists with non-matching lengths, should be doable reasonably safe.
If you insist on an actual variable number of function arguments (I don't think this is good!) then you need quite some type-class hackery. Such variadic functions are best known from printf.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
class ChainedFunc f t where
chainIfxs :: [t->t->t] -> t -> f
chainIfxs fs i = chainIfxPre i id $ reverse fs
chainIfxPre :: t -> (t->t) -> [t->t->t] -> f
instance ChainedFunc t t where
chainIfxPre i f [] = f i
instance (ChainedFunc f t) => ChainedFunc (t->f) t where
chainIfxPre i fin (f:fs) x0 = chainIfxPre i (flip f x0 . fin) fs
Obviously, this is in many ways not nice at all. But, well, it works... ahm...
Main> chainIfxs [(*),(+),(-)] (2 :: Int) (3 :: Int) (4 :: Int) (5 :: Int) :: Int
15
Could this idea help you develop a general function?
Prelude> :m +Data.List
Prelude Data.List> let fs = [(-),(+),(*)]
Prelude Data.List> foldl' (\accum (i,f) -> accum `f` i) 2 (zip [3..5] fs)
15

When is a composition of catamorphisms a catamorphism?

From page 3 of http://research.microsoft.com/en-us/um/people/emeijer/Papers/meijer94more.pdf:
it is not true in general that catamorphisms are closed under composition
Under what conditions do catamorphisms compose to a catamorphism? More specifically (assuming I understood the statement correctly):
Suppose I have two base functors F and G and folds for each: foldF :: (F a -> a) -> (μF -> a) and foldG :: (G a -> a) -> (μG -> a).
Now suppose I have two algebras a :: F μG -> μG and b :: G X -> X.
When is the composition (foldG b) . (foldF a) :: μF -> X a catamorphism?
Edit: I have a guess, based on dblhelix's expanded answer: that outG . a :: F μG -> G μG must be the component at μG of some natural transformation η :: F a -> G a. I don't know whether this is right. (Edit 2: As colah points out, this is sufficient but not necessary.)
Edit 3: Wren Thornton on Haskell-Cafe adds: "If you have the right kind of distributivity property (as colah suggests) then things will work out for the particular case. But, having the right kind of distributivity property typically amounts to being a natural transformation in some appropriately related category; so that just defers the question to whether an appropriately related category always exists, and whether we can formalize what "appropriately related" means."
When is the composition (fold2 g) . (fold1 f) :: μF1 -> A a catamorphism?
When there exists an F1-algebra h :: F1 A -> A such that fold1 h = fold2 g . fold1 f.
To see that catamorphisms are in general not closed under composition, consider the following generic definitions of type-level fixed point, algebra, and catamorphism:
newtype Fix f = In {out :: f (Fix f)}
type Algebra f a = f a -> a
cata :: Functor f => Algebra f a -> Fix f -> a
cata phi = phi . fmap (cata phi) . out
For catamorphisms to compose we would need
algcomp :: Algebra f (Fix g) -> Algebra g a -> Algebra f a
Now try writing this function. It takes two functions as arguments (of types f (Fix g) -> Fix g and g a -> a respectively) and a value of type f a, and it needs to produce a value of type a. How would you do that? To produce a value of type a your only hope is to apply the function of type g a -> a, but then we are stuck: we have no means to turn a value of type f a into a value of type g a, have we?
I am not sure whether this is of any use for your purposes, but an example of a condition under which one can compose to catamorphisms is if we have a morphism from the result of the second cata to the fixed point of the second functor:
algcomp' :: (Functor f, Functor g) =>
(a -> Fix g) -> Algebra f (Fix g) -> Algebra g a -> Algebra f a
algcomp' h phi phi' = cata phi' . phi . fmap h
(Disclaimer: This is outside my area of expertise. I believe I'm correct (with caveats provided at different points), but ... Verify it yourself.)
A catamorphism can be thought of as a function that replaces constructors of a data type with other functions.
(In this example, I will be using the following data types:
data [a] = [] | a : [a]
data BinTree a = Leaf a | Branch (BinTree a) (BinTree a)
data Nat = Zero | Succ Nat
)
For example:
length :: [a] -> Nat
length = catamorphism
[] -> 0
(_:) -> (1+)
(Sadly, the catamorphism {..} syntax is not available in Haskell (I saw something similar in Pola). I've been meaning to write a quasiquoter for it.)
So, what is length [1,2,3]?
length [1,2,3]
length (1 : 2 : 3 : [])
length (1: 2: 3: [])
1+ (1+ (1+ (0 )))
3
That said, for reasons that will become apparent later, it is nicer to define it as the trivially equivalent:
length :: [a] -> Nat
length = catamorphism
[] -> Zero
(_:) -> Succ
Let's consider a few more example catamorphisms:
map :: (a -> b) -> [a] -> b
map f = catamorphism
[] -> []
(a:) -> (f a :)
binTreeDepth :: Tree a -> Nat
binTreeDepth = catamorphism
Leaf _ -> 0
Branch -> \a b -> 1 + max a b
binTreeRightDepth :: Tree a -> Nat
binTreeRightDepth = catamorphism
Leaf _ -> 0
Branch -> \a b -> 1 + b
binTreeLeaves :: Tree a -> Nat
binTreeLeaves = catamorphism
Leaf _ -> 1
Branch -> (+)
double :: Nat -> Nat
double = catamorphism
Succ -> Succ . Succ
Zero -> Zero
Many of these can be nicely composed to form new catamorphisms. For example:
double . length . map f = catamorphism
[] -> Zero
(a:) -> Succ . Succ
double . binTreeRightDepth = catamorphism
Leaf a -> Zero
Branch -> \a b -> Succ (Succ b)
double . binTreeDepth also works, but it is almost a miracle, in a certain sense.
double . binTreeDepth = catamorphism
Leaf a -> Zero
Branch -> \a b -> Succ (Succ (max a b))
This only works because double distributes over max... Which is pure coincidence. (The same is true with double . binTreeLeaves.) If we replaced max with something that didn't play as nicely with doubling... Well, let's define ourselves a new friend (that doesn't get along as well with the others). For a binary operators that double doesn't distribute over, we'll use (*).
binTreeProdSize :: Tree a -> Nat
binTreeProdSize = catamorphism
Leaf _ -> 0
Branch -> \a b -> 1 + a*b
Let's try to establish sufficient conditions for two catamorphisms two compose. Clearly, any catamorphism will quite happily be composed with length, double and map f because they yield their data structure without looking at the child results. For example, in the case of length, you can just replace Succ and Zero with what ever you want and you have your new catamorphism.
If the first catamorphism yields a data structure without looking at what happens to its children, two catamorphisms will compose into a catamorphism.
Beyond this, things become more complicated. Let's differentiate between normal constructor arguments and "recursive arguments" (which we will mark with a % sign). So Leaf a has no recursive arguments, but Branch %a %b does. Let's use the term "recursive-fixity" of a constructor to refer to the number of recursive arguments it has. (I've made up both these terms! I have no idea what proper terminology is, if there is one! Be wary of using them elsewhere!)
If the first catamorphism maps something into a zero recursive fixity constructor, everything is good!
a | b | cata(b.a)
===============================|=========================|================
F a %b %c .. -> Z | Z -> G a b .. | True
If we map children directly into a new constructor, we're also good.
a | b | cata(b.a)
===============================|=========================|=================
F a %b %c .. -> H %c %d .. | H %a %b -> G a b .. | True
If we map into a recursive fixity one constructor...
a | b | cata(b.a)
===============================|=========================|=================
F a %b %c .. -> A (f %b %c..) | A %a -> B (g %a) | Implied by g
| | distributes over f
But it isn't iff. For example, if there exist g1 g2 such that g (f a b..) = f (g1 a) (g2 b) .., that also works.
From here, the rules will just get messier, I expect.
Catamorphisms de-construct a data structure into a result value. So, in general, when you apply a catamorphism, the result is something completely different, and you cannot apply another catamorphism to it.
For example, a function that sums all elements of [Int] is a catamorphism, but the result is Int. There is no way how to apply another catamorphism on it.
However, some special catamorphisms create a result of the same type as the input. One such example is map f (for some given function f). While it de-constructs the original structure, it also creates a new list as its result. (Actually, map f can be viewed both as a catamorphism and as an anamorphism.) So if you have such a class of special catamorphisms, you can compose them.
If we consider semantic equivalence, the composition of two catamorphisms is a catamorphism, when the first one is a hylomorphism:
cata1 . hylo1 = cata2
For example (Haskell):
sum . map (^2) = foldl' (\x y -> x + y^2) 0

Hidden features of Haskell [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What are the lesser-known but useful features of the Haskell programming language. (I understand the language itself is lesser-known, but work with me. Even explanations of the simple things in Haskell, like defining the Fibonacci sequence with one line of code, will get upvoted by me.)
Try to limit answers to the Haskell core
One feature per answer
Give an example and short description of the feature, not just a link to documentation
Label the feature using bold title as the first line
User-defined control structures
Haskell has no shorthand ternary operator. The built-in if-then-else is always ternary, and is an expression (imperative languages tend to have ?:=expression, if=statement). If you want, though,
True ? x = const x
False ? _ = id
will define (?) to be the ternary operator:
(a ? b $ c) == (if a then b else c)
You'd have to resort to macros in most other languages to define your own short-circuiting logical operators, but Haskell is a fully lazy language, so it just works.
-- prints "I'm alive! :)"
main = True ? putStrLn "I'm alive! :)" $ error "I'm dead :("
Hoogle
Hoogle is your friend. I admit, it's not part of the "core", so cabal install hoogle
Now you know how "if you're looking for a higher-order function, it's already there" (ephemient's comment). But how do you find that function? With hoogle!
$ hoogle "Num a => [a] -> a"
Prelude product :: Num a => [a] -> a
Prelude sum :: Num a => [a] -> a
$ hoogle "[Maybe a] -> [a]"
Data.Maybe catMaybes :: [Maybe a] -> [a]
$ hoogle "Monad m => [m a] -> m [a]"
Prelude sequence :: Monad m => [m a] -> m [a]
$ hoogle "[a] -> [b] -> (a -> b -> c) -> [c]"
Prelude zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
The hoogle-google programmer is not able to write his programs on paper by himself the same way he does with the help of the computer. But he and the machine together are a forced not* to be reckoned with.
Btw, if you liked hoogle be sure to check out hlint!
My brain just exploded
If you try to compile this code:
{-# LANGUAGE ExistentialQuantification #-}
data Foo = forall a. Foo a
ignorefoo f = 1 where Foo a = f
You will get this error message:
$ ghc Foo.hs
Foo.hs:3:22:
My brain just exploded.
I can't handle pattern bindings for existentially-quantified constructors.
Instead, use a case-expression, or do-notation, to unpack the constructor.
In the binding group for
Foo a
In a pattern binding: Foo a = f
In the definition of `ignorefoo':
ignorefoo f = 1
where
Foo a = f
Free Theorems
Phil Wadler introduced us to the notion of a free theorem and we've been abusing them in Haskell ever since.
These wonderful artifacts of Hindley-Milner-style type systems help out with equational reasoning by using parametricity to tell you about what a function will not do.
For instance, there are two laws that every instance of Functor should satisfy:
forall f g. fmap f . fmap g = fmap (f . g)
fmap id = id
But, the free theorem tells us we need not bother proving the first one, but given the second it comes for 'free' just from the type signature!
fmap :: Functor f => (a -> b) -> f a -> f b
You need to be a bit careful with laziness, but this is partially covered in the original paper, and in Janis Voigtlaender's more recent paper on free theorems in the presence of seq.
Shorthand for a common list operation
The following are equivalent:
concat $ map f list
concatMap f list
list >>= f
Edit
Since more details were requested...
concat :: [[a]] -> [a]
concat takes a list of lists and concatenates them into a single list.
map :: (a -> b) -> [a] -> [b]
map maps a function over a list.
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap is equivalent to (.) concat . map: map a function over a list, and concatenate the results.
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
A Monad has a bind operation, which is called >>= in Haskell (or its sugared do-equivalent). List, aka [], is a Monad. If we substitute [] for m in the above:
instance Monad [] where
(>>=) :: [a] -> (a -> [b]) -> [b]
return :: a -> [a]
What's the natural thing for the Monad operations to do on a list? We have to satisfy the monad laws,
return a >>= f == f a
ma >>= (\a -> return a) == ma
(ma >>= f) >>= g == ma >>= (\a -> f a >>= g)
You can verify that these laws hold if we use the implementation
instance Monad [] where
(>>=) = concatMap
return = (:[])
return a >>= f == [a] >>= f == concatMap f [a] == f a
ma >>= (\a -> return a) == concatMap (\a -> [a]) ma == ma
(ma >>= f) >>= g == concatMap g (concatMap f ma) == concatMap (concatMap g . f) ma == ma >>= (\a -> f a >>= g)
This is, in fact, the behavior of Monad []. As a demonstration,
double x = [x,x]
main = do
print $ map double [1,2,3]
-- [[1,1],[2,2],[3,3]]
print . concat $ map double [1,2,3]
-- [1,1,2,2,3,3]
print $ concatMap double [1,2,3]
-- [1,1,2,2,3,3]
print $ [1,2,3] >>= double
-- [1,1,2,2,3,3]
Nestable multiline comments.
{- inside a comment,
{- inside another comment, -}
still commented! -}
Generalized algebraic data types. Here's an example interpreter where the type system lets you cover all the cases:
{-# LANGUAGE GADTs #-}
module Exp
where
data Exp a where
Num :: (Num a) => a -> Exp a
Bool :: Bool -> Exp Bool
Plus :: (Num a) => Exp a -> Exp a -> Exp a
If :: Exp Bool -> Exp a -> Exp a -> Exp a
Lt :: (Num a, Ord a) => Exp a -> Exp a -> Exp Bool
Lam :: (a -> Exp b) -> Exp (a -> b) -- higher order abstract syntax
App :: Exp (a -> b) -> Exp a -> Exp b
-- deriving (Show) -- failse
eval :: Exp a -> a
eval (Num n) = n
eval (Bool b) = b
eval (Plus e1 e2) = eval e1 + eval e2
eval (If p t f) = eval $ if eval p then t else f
eval (Lt e1 e2) = eval e1 < eval e2
eval (Lam body) = \x -> eval $ body x
eval (App f a) = eval f $ eval a
instance Eq a => Eq (Exp a) where
e1 == e2 = eval e1 == eval e2
instance Show (Exp a) where
show e = "<exp>" -- very weak show instance
instance (Num a) => Num (Exp a) where
fromInteger = Num
(+) = Plus
Patterns in top-level bindings
five :: Int
Just five = Just 5
a, b, c :: Char
[a,b,c] = "abc"
How cool is that! Saves you that call to fromJust and head every now and then.
Optional Layout
You can use explicit braces and semicolons instead of whitespace (aka layout) to delimit blocks.
let {
x = 40;
y = 2
} in
x + y
... or equivalently...
let { x = 40; y = 2 } in x + y
... instead of ...
let x = 40
y = 2
in x + y
Because layout is not required, Haskell programs can be straightforwardly produced by other programs.
seq and ($!) only evaluate enough to check that something is not bottom.
The following program will only print "there".
main = print "hi " `seq` print "there"
For those unfamiliar with Haskell, Haskell is non-strict in general, meaning that an argument to a function is only evaluated if it is needed.
For example, the following prints "ignored" and terminates with success.
main = foo (error "explode!")
where foo _ = print "ignored"
seq is known to change that behavior by evaluating to bottom if its first argument is bottom.
For example:
main = error "first" `seq` print "impossible to print"
... or equivalently, without infix ...
main = seq (error "first") (print "impossible to print")
... will blow up with an error on "first". It will never print "impossible to print".
So it might be a little surprising that even though seq is strict, it won't evaluate something the way eager languages evaluate. In particular, it won't try to force all the positive integers in the following program. Instead, it will check that [1..] isn't bottom (which can be found immediately), print "done", and exit.
main = [1..] `seq` print "done"
Operator Fixity
You can use the infix, infixl or infixr keywords to define operators associativity and precedence. Example taken from the reference:
main = print (1 +++ 2 *** 3)
infixr 6 +++
infixr 7 ***,///
(+++) :: Int -> Int -> Int
a +++ b = a + 2*b
(***) :: Int -> Int -> Int
a *** b = a - 4*b
(///) :: Int -> Int -> Int
a /// b = 2*a - 3*b
Output: -19
The number (0 to 9) after the infix allows you to define the precedence of the operator, being 9 the strongest. Infix means no associativity, whereas infixl associates left and infixr associates right.
This allows you to define complex operators to do high level operations written as simple expressions.
Note that you can also use binary functions as operators if you place them between backticks:
main = print (a `foo` b)
foo :: Int -> Int -> Int
foo a b = a + b
And as such, you can also define precedence for them:
infixr 4 `foo`
Avoiding parentheses
The (.) and ($) functions in Prelude have very convenient fixities, letting you avoid parentheses in many places. The following are equivalent:
f (g (h x))
f $ g $ h x
f . g $ h x
f . g . h $ x
flip helps too, the following are equivalent:
map (\a -> {- some long expression -}) list
flip map list $ \a ->
{- some long expression -}
Pretty guards
Prelude defines otherwise = True, making complete guard conditions read very naturally.
fac n
| n < 1 = 1
| otherwise = n * fac (n-1)
C-Style Enumerations
Combining top-level pattern matching and arithmetic sequences gives us a handy way to define consecutive values:
foo : bar : baz : _ = [100 ..] -- foo = 100, bar = 101, baz = 102
Readable function composition
Prelude defines (.) to be mathematical function composition; that is, g . f first applies f, then applies g to the result.
If you import Control.Arrow, the following are equivalent:
g . f
f >>> g
Control.Arrow provides an instance Arrow (->), and this is nice for people who don't like to read function application backwards.
let 5 = 6 in ... is valid Haskell.
Infinite Lists
Since you mentioned fibonacci, there is a very elegant way of generating fibonacci numbers from an infinite list like this:
fib#(1:tfib) = 1 : 1 : [ a+b | (a,b) <- zip fib tfib ]
The # operator allows you to use pattern matching on the 1:tfib structure while still referring to the whole pattern as fib.
Note that the comprehension list enters an infinite recursion, generating an infinite list. However, you can request elements from it or operate them, as long as you request a finite amount:
take 10 fib
You can also apply an operation to all elements before requesting them:
take 10 (map (\x -> x+1) fib)
This is thanks to Haskell's lazy evaluation of parameters and lists.
Flexible specification of module imports and exports
Importing and exporting is nice.
module Foo (module Bar, blah) -- this is module Foo, export everything that Bar expored, plus blah
import qualified Some.Long.Name as Short
import Some.Long.Name (name) -- can import multiple times, with different options
import Baz hiding (blah) -- import everything from Baz, except something named 'blah'
If you're looking for a list or higher-order function, it's already there
There's sooo many convenience and higher-order functions in the standard library.
-- factorial can be written, using the strict HOF foldl':
fac n = Data.List.foldl' (*) 1 [1..n]
-- there's a shortcut for that:
fac n = product [1..n]
-- and it can even be written pointfree:
fac = product . enumFromTo 1
Equational Reasoning
Haskell, being purely functional allows you to read an equal sign as a real equal sign (in the absence of non-overlapping patterns).
This allows you to substitute definitions directly into code, and in terms of optimization gives a lot of leeway to the compiler about when stuff happens.
A good example of this form of reasoning can be found here:
http://www.haskell.org/pipermail/haskell-cafe/2009-March/058603.html
This also manifests itself nicely in the form of laws or RULES pragmas expected for valid members of an instance, for instance the Monad laws:
returrn a >>= f == f a
m >>= return == m
(m >>= f) >>= g == m >>= (\x -> f x >>= g)
can often be used to simplify monadic code.
Laziness
Ubiquitous laziness means you can do things like define
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
But it also provides us with a lot of more subtle benefits in terms of syntax and reasoning.
For instance, due to strictness ML has to deal with the value restriction, and is very careful to track circular let bindings, but in Haskell, we can let every let be recursive and have no need to distinguish between val and fun. This removes a major syntactic wart from the language.
This indirectly gives rise to our lovely where clause, because we can safely move computations that may or may not be used out of the main control flow and let laziness deal with sharing the results.
We can replace (almost) all of those ML style functions that need to take () and return a value, with just a lazy computation of the value. There are reasons to avoid doing so from time to time to avoid leaking space with CAFs, but such cases are rare.
Finally, it permits unrestricted eta-reduction (\x -> f x can be replaced with f). This makes combinator oriented programming for things like parser combinators much more pleasant than working with similar constructs in a strict language.
This helps you when reasoning about programs in point-free style, or about rewriting them into point-free style and reduces argument noise.
Parallel list comprehension
(Special GHC-feature)
fibs = 0 : 1 : [ a + b | a <- fibs | b <- tail fibs ]
Enhanced pattern matching
Lazy patterns
Irrefutable patterns
let ~(Just x) = someExpression
See pattern matching
Enumerations
Any type which is an instance of Enum can be used in an arithmetic sequence, not just numbers:
alphabet :: String
alphabet = ['A' .. 'Z']
Including your own datatypes, just derive from Enum to get a default implementation:
data MyEnum = A | B | C deriving(Eq, Show, Enum)
main = do
print $ [A ..] -- prints "[A,B,C]"
print $ map fromEnum [A ..] -- prints "[0,1,2]"
Monads
They are not that hidden, but they are simply everywhere, even where you don't think of them (Lists, Maybe-Types) ...

Resources