简体   繁体   English

仅在isJust时应用函数

[英]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] ? 我可以在不必将Maybe Creature转换为[Creature]吗?

You can do this as long as type of world and moveCreature (fromJust c) world are same. 只要world类型和moveCreature (fromJust c) world相同,你就可以做到这一点。 You can use maybe from Data.Maybe . 您可以使用maybeData.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. 我推荐使用maybe函数。 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. 你提出这个问题是正确的,因为这个一般的经验法则(不仅适合你,而且适合任何新人阅读):类似Maybe Foo -> BarMaybe Foo -> Maybe Bar的函数是直接定义的Haskell中的代码味道 You almost never want to write a function that takes Maybe Foo as an argument; 你几乎从不想写一个以Maybe Foo为参数的函数; you want a function that takes just Foo , and use a higher-order function to adapt it to Maybe Foo . 你想要一个只需要Foo的函数,并使用一个更高阶的函数来使它适应Maybe Foo

Suppose you have a function f' :: Maybe Foo -> Maybe Bar . 假设你有一个函数f' :: Maybe Foo -> Maybe Bar This can usually be refactored into either: 这通常可以重构为:

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

First case works because this is the Functor instance for Maybe : 第一种情况有效,因为这是MaybeFunctor实例:

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 : 第二种情况有效,因为这是MaybeMonad实例:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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