Basic Haskell functions

I am new to Haskell and I am trying to learn the basics. I need to declare the Pos type for the position, which will be two integers, and then I need to have North, South, West, East directions so that I can change the position based on the direction. Once I do that, I need to make a function called "moves" that will take the list of moves and the starting position and return the position after all the moves. Here is my code, but I am stuck at the point that I need to iterate over the list of moves.

type Pos = (Int, Int)
data Direction = North | South | East | West

move :: Direction -> Pos -> Pos
move North (x,y) = (x, y+1)
move West (x,y) = (x-1, y)
move South (x,y) = (x, y-1)
move East (x,y) = (x+1, y)

moves :: [Direction] -> Pos -> Pos
moves [] (x,y) = (x,y)
moves (h:xs) (x,y) 
        | h == North = move North (x,y)
        | h == West  = move West (x,y)
        | h == South = move South (x,y)
        | otherwise  = move East (x,y)

      

What am I missing here?

+3


source to share


2 answers


Either before or after the only move that matches h

, you need to make a recursive call moves

for the rest of Direction

s. If before, each case becomes something like:

move North (moves xs (x,y))

      

if you want it after, which is probably the correct approach given the specification of the problem, then it would be:

moves xs (move North (x,y))

      

However, repeating the parsing of the case in moves

is a bit unnecessary, since you can simply call move

directly with h

, eg.



moves (h:xs) (x,y) = moves xs (move h (x,y))

      

In fact, you don't even need to explicitly match patterns in the tuple (x,y)

;

moves (h:xs) pos = moves xs (move h pos)

      

As another answer points out, this is the same as a built-in function foldl

(down to the order of the arguments), but it is probably best to understand how to do it manually.

+3


source


Combining a list of things into one thing is called collapsing the list. There are (approximately) two folds of the list: foldl

and foldr

. Relying on the use of folds is an important step in learning Haskell. We need foldl

one that has the type

foldl :: (a -> b -> a) -> a -> [b] -> a

      

Now foldl

works with a merge function and an initial value to merge stuff in a list like

foldl (£) s [x,y,z] = (((s £ x) £ y) £ z)

      

( l

in foldl

is short for left, so it helps you remember that your starting value s

will end on the left, but more importantly, the parentheses are linked to the left).

The third argument is the list argument [b]

. We will use this for the list of moves, so the type b

will be Direction

.

The second argument is the start value of the type a

, so we'll use that for your start position, so the type a

will be Pos

.

The first argument is a function to combine something from your list with the current value. Now that we know that the types b

and a

are Direction

and Pos

, we know that our union function must have a type Pos -> Direction -> Pos

. The move function is pretty much what we want, except that we need to change the arguments. The function flip

does this, so it flip move

has the type we need.

So we will specialize the type foldl

as



foldl :: (Pos -> Direction -> Pos) -> Pos -> [Direction] -> Pos

      

and define

moves :: [Direction] -> Pos -> Pos
moves ds i = foldl (flip move) i ds

      


Now foldl

has a "strict" version called it foldl'

, which is faster in this case, so if you've been using it in a fast-paced game or doing very many moves, you would want to use this one.

As always, you can find functions by searching for their name or type on hoogle .

There is also a foldr function that folds the list in a different way. You can read about the difference between the two in this question . In short, it foldr

works like this:

foldr (?) s [x,y,z] = (x ? (y ? (z ? s)))

      

( r

In foldr

a short to the right, so it will help you remember what the initial value s

will be right, but, more importantly, that the brackets are connected to the right.)

+9


source







All Articles