Q:

Using anonymous functions in Haskell CIS194 Week 2 Exercise 2

I am trying to learn haskell through the "CIS 194: Introduction to Haskell 2013" course and have run into a snag with exercise 2 in the second week. I am trying to define my build function using an auxiliary recursive function
reduce :: (a -> b -> b) -> [a] -> b -> b
reduce _ [] x = x
reduce f (x:xs) y  = reduce f xs (f x y)

The goal of this function is to recursively apply a function on the list [a] to the b. This is because I want to recursively insert a list of LogMessage's into a MessageTree
build :: [LogMessage] -> MessageTree
build [] = Node Leaf (Unknown "") Leaf
build messages =
    reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf)

but when I try and compile this, I am receiving a long list of compilation errors:
LogAnalysis.hs:42:22:
    Couldn't match expected type `t0 -> MessageTree'
                with actual type `MessageTree'
    In the return type of a call of `insert'
    Probable cause: `insert' is applied to too many arguments
    In the expression: (insert x y)
    In the first argument of `reduce', namely `(\ x y -> (insert x y))'

LogAnalysis.hs:42:31:
    Couldn't match expected type `MessageTree'
                with actual type `t0 -> MessageTree'
    In the second argument of `insert', namely `y'
    In the expression: (insert x y)
    In the first argument of `reduce', namely `(\ x y -> (insert x y))'

LogAnalysis.hs:42:35:
    Couldn't match expected type `[LogMessage]'
                with actual type `[a0] -> [a0]'
    In the second argument of `reduce', namely `tail'
    In the expression:
      reduce
        (\ x y -> (insert x y))
        tail
        (messages)
        (Node Leaf head (messages) Leaf)
    In an equation for `build':
        build messages
          = reduce
              (\ x y -> (insert x y))
              tail
              (messages)
              (Node Leaf head (messages) Leaf)

LogAnalysis.hs:42:40:
    Couldn't match expected type `t0 -> MessageTree'
                with actual type `[LogMessage]'
    In the third argument of `reduce', namely `(messages)'
    In the expression:
      reduce
        (\ x y -> (insert x y))
        tail
        (messages)
        (Node Leaf head (messages) Leaf)
    In an equation for `build':
        build messages
          = reduce
              (\ x y -> (insert x y))
              tail
              (messages)
              (Node Leaf head (messages) Leaf)

LogAnalysis.hs:42:51:
    Couldn't match expected type `MessageTree -> t0'
                with actual type `MessageTree'
    The function `Node' is applied to four arguments,
    but its type `MessageTree
              -> LogMessage -> MessageTree -> MessageTree'
    has only three
    In the fourth argument of `reduce', namely
      `(Node Leaf head (messages) Leaf)'
    In the expression:
      reduce
        (\ x y -> (insert x y))
        tail
        (messages)
        (Node Leaf head (messages) Leaf)

LogAnalysis.hs:42:61:
    Couldn't match expected type `LogMessage'
            with actual type `[a1] -> a1'
    In the second argument of `Node', namely `head'
    In the fourth argument of `reduce', namely
      `(Node Leaf head (messages) Leaf)'
    In the expression:
      reduce
        (\ x y -> (insert x y))
        tail
        (messages)
        (Node Leaf head (messages) Leaf)

LogAnalysis.hs:42:66:
    Couldn't match expected type `MessageTree'
            with actual type `[LogMessage]'
    In the third argument of `Node', namely `(messages)'
    In the fourth argument of `reduce', namely
      `(Node Leaf head (messages) Leaf)'
    In the expression:
      reduce
        (\ x y -> (insert x y))
        tail
        (messages)
        (Node Leaf head (messages) Leaf)
Failed, modules loaded: Log.

For reference, here is my insert function, which compiles correctly
insert :: LogMessage -> MessageTree -> MessageTree
insert (Unknown _) tree = tree
insert _ tree@(Node _ (Unknown _) _) = tree
insert message Leaf = Node Leaf message Leaf
insert message@(LogMessage _ timeStampMessage _) (Node left m@(LogMessage _ timeStampTree _) right)
    | timeStampMessage < timeStampTree  = Node (insert message left) m right
    | timeStampMessage > timeStampTree  = Node left m (insert message right)
    | timeStampMessage == timeStampTree = Node left message right

A:

Parentheses do not indicate function calls; they simply affect operator precedence. Function application is represented by juxtaposition (which can be thought of as the operator with highest precedence).
This line
build messages = reduce (\x y -> (insert x y)) tail(messages) (Node Leaf head(messages) Leaf)

should first be shortened to 
build messages = reduce insert tail(messages) (Node Leaf head(messages) Leaf)

which makes it easier to see the correct way to parenthesize:
build messages = reduce insert (tail messages) (Node Leaf (head messages) Leaf)

This is, however, better written using pattern matching than using head and tail:
build (x:xs) = reduce insert xs (Node Leaf x Leaf)

