eaz*_*001 3 haskell boilerplate functor
我有一些数据类型Verb p定义如下:
data Verb p = Look {getPreps :: p}
| LookExtra {getPreps :: p}
| Touch {getPreps :: p}
| Smell {getPreps :: p}
| HearExtra {getPreps :: p}
| Hear {getPreps :: p}
| Taste {getPreps :: p}
| Pickup {getPreps :: p}
| PickupExtra {getPreps :: p}
| Move {getPreps :: p}
| MoveExtra {getPreps :: p}
deriving (Show,Ord,Eq)
Run Code Online (Sandbox Code Playgroud)
我必须使这个数据类型成为Functor至少一个实例.因此:
instance Functor Verb where
fmap f (Look a) = Look (f a)
fmap f (LookExtra a) = LookExtra (f a)
fmap f (Touch a) = Touch (f a)
fmap f (Smell a) = Smell (f a)
fmap f (HearExtra a) = HearExtra (f a)
fmap f (Hear a) = Hear (f a)
fmap f (Taste a) = Taste (f a)
fmap f (Pickup a) = Pickup (f a)
fmap f (PickupExtra a) = PickupExtra (f a)
fmap f (Move a) = Move (f a)
fmap f (MoveExtra a) = MoveExtra (f a)
Run Code Online (Sandbox Code Playgroud)
如果那不是样板,那么我不知道是什么.我可以想象,如果我不得不前进Applicative Functors等等,这将成为一种真正的痛苦.有没有更好的方法来写这个而不改变Verb p完全的结构?由于我编写的方式Verb p,似乎我注定要为每个数据类型构造函数声明一个实例.希望我被证明是错的.
lef*_*out 12
看看DeriveFunctor扩展名.正如名称提示,它允许您简单地添加Functor到deriving列表中.不幸的是,这并没有扩展到Applicative并且Monad因为,与Functor那些通常没有一种方法来定义实例,而是多种非等效的可能性.
在您的示例中,我将简化数据定义:
data VerbType = Look | LookExtra | ...
type Verb a = (VerbType, a)
-- or data Verb a = Verb { verbType :: VerbType, getPreps :: a }
Run Code Online (Sandbox Code Playgroud)