[英]An example of a type with kind * -> * which cannot be an instance of Functor
[英]Functor instance of kind *
我有新类型:
newtype Foo = Foo ([Int])
我想简单地应用Int -> Int
function ,就像使用 fmap 一样。
我认为派生或实现Functor
实例就足够了,但它需要* -> *
类型。
是否有一些内置方法可以使我的类型部分fmap
?
{-# LANGUAGE TypeFamilies #-}
type instance Element Foo = Int
instance MonoFunctor Foo where
-- omap :: (Int -> Int) -> Foo -> Foo
omap = ...
在得意忘形之前,您应该记住,您要避免 (1) 命名和 (2) 编写单态 function:
mapFoo :: (Int -> Int) -> (Foo -> Foo)
mapFoo f (Foo ints) = Foo (f <$> ints)
如果您真的不想给这个 function 一个单独的名称,并希望 GHC 为您编写 function,我认为唯一明智的方法是将您的类型重新定义为类型的正确函子* -> *
自动派生实例:
newtype FooF a = Foo [a] deriving (Functor)
然后为Int
的特化定义一个类型别名:
type Foo = FooF Int
这并不完全等同于您对Foo
的原始定义。 特别是,以下表达式是孤立的:
Foo [1,2,3]
将具有类型Num a => FooF a
而不是类型Foo = FooF Int
,因此 GHC 可能无法在它过去的所有位置推断类型。 但是,这个Foo
类型别名主要表现得像你原来的Foo
新类型,并允许你写:
fmap (*5) $ Foo [1,2,3]
等等。
另一方面,如果你想保持你的新类型相同,不要介意自己写 function,但又不想给 function 一个单独的名字,你不能使用fmap
(至少不是不覆盖前奏定义,哪一种违背了目的)。 但是,根据@leftroundabout 的回答,您可以使用mono-traversable
omap
中的 omap。 因为这需要您在MonoFunctor Foo
实例中自己定义 function (例如,使用与上面的mapFoo
相同的定义),所以没有真正的意义,除非您为Foo
之外的一堆非仿函数执行此操作并且想要使用一个omap
名称,或者想要编写可以统一处理任何此类MonoFunctor
的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.