2012-10-26 7 views
5

ich für eine idiomatische Weise tuneine Funktion gelten nur, wenn isjust

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

Oder mit anderen Worten

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

Ich dachte, freue ich es auf diese Weise könnte:

moveMaybeCreature c w = foldr moveCreature w (maybeToList c) 

Kann ich es ohne Maybe Creature zu [Creature] konvertieren?

Antwort

10

Sie können dies tun, solange der Typ world und moveCreature (fromJust c) world gleich sind. Sie können maybe von Data.Maybe verwenden.

Ihre erste Art zu tun, wo Sie Muster übereinstimmen, sollte auch gut funktionieren.

+1

Das ist die erste Funktion auf dem Dokument für Data.Maybe beschrieben, und ich habe es irgendwie verpasst. Vielen Dank! – Niriel

+0

Als Randnotiz gibt es auch die Entsprechung für "Entweder": "Entweder" in "Daten.immer". – David

+1

Deine Vorraussetzung für die Typen ist ziemlich garantiert, wenn 'moveMaybeCreature 'an erster Stelle geprüft wird ... –

5

Ich zweite die Empfehlung, die maybe Funktion zu verwenden. Sie haben diese Frage aufgrund dieser allgemeinen Faustregel richtig gestellt (nicht nur für Sie, sondern auch für Neulinge, die es lesen): Funktionen mit direkt definierten Typen wie Maybe Foo -> Bar oder Maybe Foo -> Maybe Bar sind code smell in Haskell. Sie möchten fast nie eine Funktion schreiben, die Maybe Foo als ein Argument nimmt; Sie möchten eine Funktion, die nur Foo verwendet, und eine höherwertige Funktion verwenden, um sie an Maybe Foo anzupassen.

Angenommen, Sie haben eine Funktion f' :: Maybe Foo -> Maybe Bar. Dies kann in der Regel entweder in Refactoring:

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

Erster Fall funktioniert, weil dies die Functor Instanz für Maybe:

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

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

Zweiter Fall funktioniert, weil das ist die Monad Instanz für Maybe:

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

-- or this: 
--  mx >>= f = maybe Nothing f mx 
+0

.... und wie Satvik sagte, wenn Sie eine Funktion vom Typ "Maybe a -> b" wie Ihre haben, können Sie die 'may' Funktion verwenden, um sie zu refaktorieren. – AndrewC

+1

Interessanterweise, wenn Sie eine Funktion wie 'vielleicht :: a -> b -> Vielleicht c -> Vielleicht d -> Vielleicht e -> Vielleicht f 'schreiben, können Sie Applicative verwenden und das reine Bit unter der Annahme aller vielleicht schreiben Daten sind verfügbar und definieren "vielleicht = reinbit ab <$> c <*> d <*> e". – AndrewC

3

Hier ist noch ein Opt Ion, näher an Ihrem ursprünglichen Code:

Verwandte Themen