Home > Software design >  Wrap a partial pattern matching into a Maybe
Wrap a partial pattern matching into a Maybe

Time:02-05

Is there any way to wrap a partial pattern-match into a Maybe?

I wish to write some code kind of like this:

fromMaybe defaultValue $ do
  [a, b] <- mkList :: [Int]
  [x] <- mkList' a b :: [Int]
  return $ x

where this expression's value would be defaultValue if mkList evaluates to a list with length /= 2, or if mkList' a b evaluates to a list of length /= 1. Otherwise the expression evaluates to the only element returned by mkList' a b.

I figured the Maybe monad would be great to achieve this. But how can I turn a failed pattern-matching into a Nothing, and a successful match into a Just?

Is it possible to achieve this in Haskell?

CodePudding user response:

Your code almost works as is. You only need to add some pure and change the type:

import Data.Maybe

f defaultValue mkList mkList' = fromMaybe defaultValue $ do
  [a, b] <- pure mkList :: Maybe [Int]
  [x] <- pure (mkList' a b) :: Maybe [Int]
  return x

You don't even need those :: Maybe [Int] annotations.

In GHCi you can see it has the expected behavior:

ghci> f 0 [1,2,3] (\x y -> [x,y])
0
ghci> f 0 [1,2] (\x y -> [x])
1
ghci> f 0 [1,2] (\x y -> [y])
2
ghci> f 0 [1,2] (\x y -> [x,y])
0
  • Related