The list type is generally used for parser combinators to return multiple possible parses.

I don't own Hutton's book, but I can think of a few reasons for not using Maybe. It would require introducing a new datatype to the reader, while the reader is already familiar with the list type. Also, it takes more characters to write when pattern matching
on a Maybe value .

Now, in a real project you'd use the appropiate data type. If you know that at most only a single answer will be produced, use Maybe.

"Also you might define functions with time-guarantees, that forcefully stop prematurely if they cannot complete within some time;"

Hmm, that's not an easytask. You'd need to encode values as types or you need type constructors that also accept values instead of only types. For example, you'd love to write code like this then:

-- an Int to Int function that takes at most 5 time units someComputation :: Int -> RealTime 5 Int

But now you might also want to do arithmetic at the type level:

-- an example, the type of a function that adds two real-time int results: add :: RealTime t1 Int -> RealTime t2 Int -> RealTime (t1+t2) Int

"The question is: for infinite time, you have bottom, i.e. non-termination. But how much time is bottom? Is it always sufficient to say infinite time or wouldn't it make sense to define more soft times?"

Bottom is the result of anything that fails to produce an answer. I wouldn't overload bottom for computations that do not finish in time, but use the type system instead to tag your values:

-- pseudo-Haskell (no support for values at the type level) data RealTime <Int> a = Result a -- the result of a successful RealTime computation | Aborted -- the result of a computation that took too long

concat :: [[a]] -> [a] -- generalized: join :: Monad m => m (m a) -> m a {- if you sub m=[], you'll get: join :: [] ([] a) -> [] a = join :: [[a]] -> [a] :) -} -- dual of join: duplicate :: Comonad w => w a -> w (w a) -- but I'm not well
versed in the area of comonads :p

Re: parentheses, the ones around the lambda are just the same as in any ordinary expression, for example:

foo x y = x * (y+x)

About the language being able to deconstruct lists, that's because Haskell is designed to deconstruct
any algebraic data type (ADT).

-- ADT for a linked list: data List a -- [a] <--> List a = Cons a (List a) -- (:) <--> Cons | Nil -- [] <--> Nil -- ADT for a binary tree: data BTree a = Node (BTree a) (BTree a) | Empty

And yes, your drop2 function does exactly what you say it does, although you don't need the inner parentheses in the pattern.

About the minus business, yes, that's a syntax quirk.

Function application is like search/replace. If we have the following definition:

add = \x -> (\y -> x+y)

If we apply the function to e.g. 3, we'll get:

add 3 = {- replace add by its definition -} (\x -> (\y -> x+y)) 3 = {- now substitiute 3 for x, i.e. function application -} {- no further substitution possible -}

Now, if we'll apply this result to e.g. 4, we'll get:

(\y -> 3+y) 4 = {- function application, sub 4 for y -} 3+4 = {- use the definition of (+) -} 7

I don't think it's a good idea if a function would automatically be transformed to a point-free notation by the IDE. Sometimes the point-free version is much harder to read**. Nevertheless, it would be a great optional tool in an IDE.

** Example:

-- pointful: mult x y z = z*y*x -- pointfree generated by lambdabot's @pl tool: mult = flip (flip . ((*) .) . (*))

Btw, the pointfree version of this example can be made simpler if you'll use the commutativity of (*). The only problem is that the commutativity property is not garantueed, so a (syntactic) pointfree tool cannot rely on it.

## Comments

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 8 of 13

The list type is generally used for parser combinators to return multiple possible parses.

I don't own Hutton's book, but I can think of a few reasons for not using Maybe. It would require introducing a new datatype to the reader, while the reader is already familiar with the list type. Also, it takes more characters to write when pattern matching on a Maybe value .

Now, in a real project you'd use the appropiate data type. If you know that at most only a single answer will be produced, use Maybe.

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 5 of 13

"Also you might define functions with time-guarantees, that forcefully stop prematurely if they cannot complete within some time;"Hmm, that's not an easytask. You'd need to encode values as types or you need type constructors that also accept values instead of only types. For example, you'd love to write code like this then:

But now you might also want to do arithmetic at the type level:

I think this is getting quite tricky real fast.

(There is a nice way however to pass values around at the type level, see this paper: Functional Pearl: Implicit Configurations —or, Type Classes Reflect the Values of Types)

"The question is: for infinite time, you have bottom, i.e. non-termination. But how much time is bottom? Is it always sufficient to say infinite time or wouldn't it make sense to define more soft times?"Bottom is the result of anything that fails to produce an answer. I wouldn't overload bottom for computations that do not finish in time, but use the type system instead to tag your values:

Edit:Just found this, might also be an interesting read: Pausable IO actions for better GUI responsiveness.

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 6 of 13

It seems that the animation got lost in the full screen slides.

Anyway, if anyone gets stuck on implementing a more efficient reverse function, here's a hint:

accumulator.About the presented Haskell zip function, its definition can be shorter if you reorder the clauses:

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 5 of 13

Well, ask yourself this: is time always an effect? For example, does the result of sqrt(9) depend on the current time?

But when time does have an effect on the result, the type system should track it. For example, getCurrentTime in Haskell has type IO UTCTime.

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 5 of 13

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 5 of 13

Talking about unfolds, someone from #haskell once wrote a beautiful implementation using a GHC extension

here on hpaste.## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 4 of 13

Re: parentheses, the ones around the lambda are just the same as in any ordinary expression, for example:

About the language being able to deconstruct lists, that's because Haskell is designed to deconstruct

algebraic data type (ADT).anyAnd yes, your drop2 function does exactly what you say it does, although you don't need the inner parentheses in the pattern.

About the minus business, yes, that's a syntax quirk.

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 4 of 13

Function application is like search/replace. If we have the following definition:

If we apply the function to e.g. 3, we'll get:

Now, if we'll apply this result to e.g. 4, we'll get:

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals Chapter 4 of 13

There are editors that replace certain Haskell symbols with their unicode equivalents. One example is emacs as shown in this blog post.

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals, Chapter 3 of 13

The slides can be found here.

## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals, Chapter 3 of 13

I don't think it's a good idea if a function would automatically be transformed to a point-free notation by the IDE. Sometimes the point-free version is much harder to read**. Nevertheless, it would be a great optional tool in an IDE.

** Example:

Btw, the pointfree version of this example can be made simpler if you'll use the commutativity of (*). The only problem is that the commutativity property is not garantueed, so a (syntactic) pointfree tool cannot rely on it.## C9 Lectures: Dr. Erik Meijer - Functional Programming Fundamentals, Chapter 3 of 13

For those who are interested, the C# zip function Erik talked about (shown below)...

...also exists in Haskell as zipWith

...and can be implemented using only two lines of Haskell.