我正在学习基本类型类,并为我的类型Test a写了自己的functor实现(与Maybe一样):
I'm learning basic type classes and have written my own implementation of functor for my type Test a (behaves just like Maybe):
data Test a = Test a | Emp class FC c a where t :: (a -> b) -> c a -> c b instance FC Test a where t f (Test a) = Test (f a) t f (Emp) = Emp instance FC Maybe a where t f (Just a) = Just (f a) t f (Nothing) = Nothing是否可以实现类似的内容:
Is it possible to implement something like:
instance FC c where t f (c v) = c (f v)错误:
Parse error in pattern: c换句话说,将类型构造函数抽象出来,替换为c和v,从而创建一个通用实例,该实例可以应用于具有上下文的任何值吗?
In other words, abstract away the type constructor, replace with c and v, therefore creating a general instance that can be applied to any value with a context?
推荐答案如您所知,c a并不是语法上有效的模式.但是,请阅读您的问题作为功能建议:这将如何工作?并非每个Functor都有一个单元素构造函数,可以根据您的模式进行映射.一些例子:
As you've learned, c a is not a syntactically valid pattern. But reading your question instead as a feature proposal: How would that work? Not every Functor has a single-element constructor which can be mapped over according to your pattern. Some examples:
data Pair a = Pair a a -- more than one element instance Functor Pair where fmap f (Pair x y) = Pair (f x) (f y) data Proxy a = Proxy -- no elements instance Functor Proxy where fmap f Proxy = Proxy newtype Cont r a = Cont { runCont :: (a -> r) -> r } -- element appears in a double-negative position instance Functor (Cont r) where fmap f (Cont g) = Cont (g . (. f))无论如何,我认为通用实例"的想法真的没有道理.该实例是您放置特定于类型的代码的地方. (它必须去某个地方!)
In any case, I don't think the idea of a "generic instance" really makes sense. The instance is where you put your type-specific code. (It has to go somewhere!)
如果您想花更少的精力编写Functor实例,则可以使用GHC的DeriveFunctor扩展名.
If you want to exert less effort in writing Functor instances you can use GHC's DeriveFunctor extension.
{-# LANGUAGE DeriveFunctor #-} data Pair a = Pair a a deriving Functor data Proxy a = Proxy deriving Functor newtype Cont r a = Cont { runCont :: (a -> r) -> r } deriving Functor更多推荐
跨类型构造函数编写泛型仿函数实例?
发布评论