Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a function only if isJust

Tags:

haskell

I am looking for a idiomatic way of doing

moveMaybeCreature Nothing world = world
moveMaybeCreature (Just creature) world = moveCreature creature world

Or in other words

if isJust c
    then doSomething (fromJust c) w
    else w

I thought I could to it this way:

moveMaybeCreature c w = foldr moveCreature w (maybeToList c)

Can I do it without having to convert Maybe Creature to [Creature]?

like image 728
Niriel Avatar asked Oct 26 '12 04:10

Niriel


2 Answers

You can do this as long as type of world and moveCreature (fromJust c) world are same. You can use maybe from Data.Maybe.

 moveMaybeCreature = maybe id moveCreature

Your first way of doing where you pattern match should also work just fine.

like image 164
Satvik Avatar answered Oct 05 '22 14:10

Satvik


I second the recommendation to use the maybe function. You were right to ask this question because of this general rule of thumb (not just for you, but for any newcomers reading it): functions with types like Maybe Foo -> Bar or Maybe Foo -> Maybe Bar that are defined directly are a code smell in Haskell. You almost never want to write a function that takes Maybe Foo as an argument; you want a function that takes just Foo, and use a higher-order function to adapt it to Maybe Foo.

Suppose you have a function f' :: Maybe Foo -> Maybe Bar. This can usually be refactored into either:

  1. f :: Foo -> Bar and fmap f :: Maybe Foo -> Maybe Bar;
  2. f :: Foo -> Maybe Bar and (>>=f) :: Maybe Foo -> Maybe Bar

First case works because this is the Functor instance for Maybe:

instance Functor Maybe where
    fmap f Nothing = Nothing
    fmap f (Just x) = Just (f x)

-- or this:
--     fmap f = maybe Nothing (Just . f)

Second case works because this is the Monad instance for Maybe:

instance Monad Maybe where
    return = Just
    Nothing >>= f = Nothing
    (Just x) >>= f = f x

-- or this:
--     mx >>= f = maybe Nothing f mx
like image 31
Luis Casillas Avatar answered Oct 05 '22 14:10

Luis Casillas