Haskell 类函子实例*

Haskell 类函子实例*,haskell,Haskell,我有一个新的类型: newtype Foo=Foo([Int]) 我想简单地在它上面应用Int->Int函数,就像使用fmap一样 我认为派生或实现Functor实例就足够了,但它需要*->*类的类型 是否有一些内置方法可以使我的类型部分成为fmap-able? 在忘乎所以之前,您应该记住,您试图避免(1)命名和(2)编写单态函数: mapFoo :: (Int -> Int) -> (Foo -> Foo) mapFoo f (Foo ints) = Foo (f <

我有一个新的类型:

newtype Foo=Foo([Int])
我想简单地在它上面应用
Int->Int
函数,就像使用fmap一样

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

是否有一些内置方法可以使我的类型部分成为
fmap
-able?


在忘乎所以之前,您应该记住,您试图避免(1)命名和(2)编写单态函数:

mapFoo :: (Int -> Int) -> (Foo -> Foo)
mapFoo f (Foo ints) = Foo (f <$> ints)
然后为专门化定义一个类型别名为
Int

type Foo = FooF Int
这与您最初对
Foo
的定义并不完全相同。具体而言,以下表达式是孤立的:

Foo [1,2,3]
将使用type
Num a=>FooF a
而不是type
Foo=FooF Int
,因此GHC可能无法在其使用的所有位置推断类型。但是,此
Foo
类型别名的行为大部分与原始
Foo
newtype类似,并允许您编写:

fmap (*5) $ Foo [1,2,3]
诸如此类


另一方面,如果您想保持新类型不变,不介意自己编写函数,但又不想给该函数一个单独的名称,则不能使用
fmap
(至少不能在不覆盖前奏曲定义的情况下使用,这样做有违目的)。但是,根据@LeftRoundound的回答,您可以使用
mono traversable
包中的
omap
。因为这需要您自己在
MonoFunctor Foo
实例中定义函数(例如,使用与上面
mapFoo
相同的定义),除非你是为一堆非functor(除了
Foo
之外)做这件事,并且想为它们使用一个
omap
名称,或者想编写能够统一处理任何此类
单functor的函数,否则没有真正的意义。

在忘乎所以之前,你应该记住你正在努力避免(1)命名和(2)编写单态函数:

mapFoo :: (Int -> Int) -> (Foo -> Foo)
mapFoo f (Foo ints) = Foo (f <$> ints)
然后为专门化定义一个类型别名为
Int

type Foo = FooF Int
这与您最初对
Foo
的定义并不完全相同。具体而言,以下表达式是孤立的:

Foo [1,2,3]
将使用type
Num a=>FooF a
而不是type
Foo=FooF Int
,因此GHC可能无法在其使用的所有位置推断类型。但是,此
Foo
类型别名的行为大部分与原始
Foo
newtype类似,并允许您编写:

fmap (*5) $ Foo [1,2,3]
诸如此类


另一方面,如果您想保持新类型不变,不介意自己编写函数,但又不想给该函数一个单独的名称,则不能使用
fmap
(至少不能在不覆盖前奏曲定义的情况下使用,这样做有违目的)。但是,根据@LeftRoundound的回答,您可以使用
mono traversable
包中的
omap
。因为这需要您自己在
MonoFunctor Foo
实例中定义函数(例如,使用与上面
mapFoo
相同的定义),没有真正的意义,除非你是为一堆除了
Foo
之外的非函子这么做的,并且想为所有这些函子使用一个
omap
名称,或者想编写能够统一处理任何此类
单函子的函数。

简短回答:这种类型不能是
函子
,as函子必须至少有一个类型变量。例如,
newtypefoo'a=Foo'([a])
将是一个函子。但是,即使这不是一个函子,仍然完全可以编写映射函数
foomap::(Int->Int)->Foo->Foo
。简短回答:此类型不能是
函子,因为函子必须至少有一个类型变量。例如,
newtypefoo'a=Foo'([a])
将是一个函子。然而,即使这不是一个函子,仍然完全可以编写映射函数
foomap::(Int->Int)->Foo->Foo