0
votes

I'm trying to return a Maybe value from a function that uses do notation, but I can't seem to get it to work. This function takes a string (The "filename") and a Path to search in...

findIn :: String -> Path -> Maybe Path
findIn search start = do
    file <- ls start
    if ((filename file) == search)
      then Just file
      else Nothing

Where...

ls :: Path -> Array Path
filename :: Path -> String

But I keep getting the error "Count not match Type Array with type Maybe", so it looks like the compiler is expecting the do notation to return an array. How would I return a maybe value?

2

2 Answers

2
votes

You can't mix monads like that.

When you write:

file <- ls start

it's a bit like saying "for each value file in the array..." so you are in the context of multiple possible values.

But then the rest of the code is in the context of Maybe, which can only handle one (or zero) values.

In the module Data.Foldable there is a find function, which does the bulk of the work of your main function, by searching for a single item that matches some criteria. Its actual type is more general, but when constrained to Arrays it's like this:

find :: forall a. (a -> Boolean) -> Array a -> Maybe a

Then you can just write:

findIn search start = find (\x => x == search) $ ls start
1
votes

Ok, I found something that works, but I'm not sure if it's ideal.

findIn :: String -> Path -> Maybe Path
findIn search start = if (length r == 1)
                      then head r
                      else Nothing
  where
    r = do
      file <- ls start
      guard $ (filename file) == search
      [file]

So it looks like the do-notation returns a value of type Array(Maybe Path) .