4

I am writing Haskell solver for simple board game. I have this function:

bestMove :: Board -> (Int,Int)
bestMove brd = minimumBy (comparing $ length.choices brd) (remaining brd)

Basically bestMove is a move which leaves the smallest amount of choices out of remaining moves. I know however that no element leaves less than one choice. How do I write this function to terminate searching for minimum if such a move is found ?
In other words I want a function which returns minimum or first encountered element which is small enough (without traversing rest of the list).

It's my first Haskell program so it's probably very basic. It's a backtracking solver so not traversing whole list in a function which is called millions of times is important.

Piotr Lopusiewicz
  • 2,514
  • 2
  • 27
  • 38

1 Answers1

3

I'll simplify your question since you don't provide types for some of your functions:

How do you write a function to take the minimum of a list, given a known lower bound on the minimum?

Such a function would have type:

minimum' :: (Ord a) => a -> [a] -> a

... where the first argument is the known lower bound (i.e. 1 choice), and the second argument is the list to search.

We can define this function by composing two simpler functions. The first function simply lazily takes all elements from the list until it reaches the lower bound or the end of the list:

chop :: (Ord a) => a -> [a] -> [a]
chop minElem as =
    let (prefix, suffix) = span (> minElem) as
    in  case suffix of
            []      -> prefix
            s:uffix -> prefix ++ [s]

Then we compose it with minimum:

minimum' minElem = minimum . chop minElem

This is a common pattern in functional programming: composing simple solutions to solve complex problems.

Gabriella Gonzalez
  • 34,863
  • 3
  • 77
  • 135