简体   繁体   中英

haskell, case of like fmap

I have a function of type foo :: a -> a -> Either String TypeConstructor
foo can return both throwError String and something of TypeConstructor .

I would like to do something like fmap . I mean that I would like to case (foo xyz) of ... where ... means different values (it depends on used constructor value in foo).

Is there exista any way to do it ?

A basic way could be to pattern match everything

case foo x y of
  Left string -> ...
  Right (Cons1 z w) -> ...
  Right (Cons2 a b c) -> ...
  Right Cons3 -> ...

where Cons1, ... are the value constructors of TypeConstructor .

You can't directly write

case (foo x y) of ...

and then pattern match on the type constructors of TypeConstructor since foo xy does not have the correct type (it is Either String TypeConstructor ).

However, you can define a function which pattern matches on the type constructors of TypeConstructor and then fmap this over the result of foo xy as shown below.

import Control.Monad.Except (throwError)

data Type = Int Int
          | Str String
          deriving (Show)

foo :: Int -> String -> Either String Type
foo n s =
    if n == 0
        then throwError "Zero"
        else return (Str s)

bar x y = fmap f (foo x y)
    where
        f a = case a of
            Int n -> Int (n +  x)
            Str s -> Str (s ++ y)

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