Plt2013 9

(C) Ralf Lämmel, Andrei Varanovich, University of Koblenz Landau



Define a function as follows.

> :t headlast
headlast :: [a] -> [(a, a)]
> headlast [1]
> headlast [1,2]
> headlast [1,2,3]
> headlast [1,2,3,4]
> headlast [1,2,3,4,5]
> headlast [1,2,3,4,5,6]

Can you think of different ways of doing it?

Revise a function as follows.

Consider the following definitional variant of foldr:

myfoldr f z l
 = if null l
     then z 
     else f (head l) (myfoldr f z (tail l))

Now let's take the view that this form is problematic because it applies partial functions head and tail even though it should be possible to make it more evident that no partiality can strike us. Thus let's assume that we have a helper function which encapsulates the kind of case ("pattern matching") on lists:

listcase :: x -> (a -> [a] -> x) -> [a] -> x

Define listcase and revise myfoldr to make use of it.

Instantiate a type class.

Consider the following data type for representing "maxima" including the case of the undefined value, with the help of the Maybe monad:

newtype MaxInt = MaxInt { getMaxInt :: Maybe Int }
 deriving (Show)

Instantiate the Monoid type class for this type so that the following computations are feasible:

> mconcat [MaxInt Nothing]
MaxInt {getMaxInt = Nothing}
> mconcat [MaxInt (Just 1), MaxInt Nothing]
MaxInt {getMaxInt = Just 1}
> mconcat [MaxInt Nothing, MaxInt (Just 2)]
MaxInt {getMaxInt = Just 2}
> mconcat [MaxInt (Just 3), MaxInt (Just 2)]
MaxInt {getMaxInt = Just 3}
> mconcat [MaxInt (Just 3), MaxInt Nothing, MaxInt (Just 2)]
MaxInt {getMaxInt = Just 3}