繁体   English   中英

类型的函子实例 *

[英]Functor instance of kind *

我有新类型:

newtype Foo = Foo ([Int])

我想简单地应用Int -> Int function ,就像使用 fmap 一样。

我认为派生或实现Functor实例就足够了,但它需要* -> *类型。

是否有一些内置方法可以使我的类型部分fmap

https://hackage.haskell.org/package/mono-traversable-1.0.15.1/docs/Data-MonoTraversable.html#t:MonoFunctor

{-# 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM