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]
将使用typeNum a=>FooF a
而不是typeFoo=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]
将使用typeNum a=>FooF a
而不是typeFoo=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
。