简体   繁体   中英

Apply a function only if isJust

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] ?

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.

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

Here's another option, closer to your original code:

import qualified Data.Foldable as F

moveMaybeCreature = flip (F.foldr moveCreature)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM