Haskell 模式f中的分析错误。fmap中的g(f.g)=fmap f。fmap g
模式f中的分析错误。g 我是初学者,哪里不对Haskell 模式f中的分析错误。fmap中的g(f.g)=fmap f。fmap g,haskell,Haskell,模式f中的分析错误。g 我是初学者,哪里不对 (f . g) x = f (g x) class Functor f where fmap :: (a -> b) -> f a -> f b class Functor g where fmap :: (a -> b) -> f a -> f b instance Functor F where fmap id = id fmap (f . g) = fm
(f . g) x = f (g x)
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor g where
fmap :: (a -> b) -> f a -> f b
instance Functor F where
fmap id = id
fmap (f . g) = fmap f . fmap g
因为
不是一个数据构造函数,所以我认为不能将它用于模式匹配。据我所知,没有一种简单的方法可以完成您正在尝试的任务,尽管我对Haskell也很陌生。让
不用于顶级绑定,只需执行以下操作:
f . g = \x -> f (g x)
但正如科巴尔所说,投诉是关于fmap(f.g),这是无效的。实际上,整个类函子F,其中是螺旋的。该类已经声明,现在我想您需要创建和实例:
instance Functor F where
fmap SomeConstructorForF = ...
fmap OtherConstructorForF = ...
等等。当你做一个函子的实例时,你应该证明
fmap id = id
及
(从技术上讲,考虑到涉及的类型和前者的法律,后者是免费的,但这仍然是一个很好的做法。)
你不能只是说
fmap id = id
但是,一旦你证明了这一点,你就可以把它作为一种推理工具
也就是说,由于许多原因,您编写的代码没有意义
(f . g) x = f (g x)
由于这是缩进的,我不太清楚这是否是(.)的定义,但它已经包含在前奏曲中,所以您无需再次定义它
class Functor f where
fmap :: (a -> b) -> f a -> f b
前奏曲中也为您提供了这一定义
class Functor g where
fmap :: (a -> b) -> f a -> f b
但是,您再次定义了这个类,但是在这里它破坏了fmap的签名,这必须是
fmap :: (a -> b) -> g a -> g b
但由于上面有函子的另一个定义(前奏曲还有另一个定义,所以无法编译)
最后,你的
instance Functor F where
fmap id = id
fmap (f . g) = fmap f . fmap g
为要生成为Functor
实例的类型生成一个名称F
,然后尝试将规则作为一个实现,这不是它的工作方式
让我们举一个它应该如何工作的例子
考虑一个非常简单的函子:
data Pair a = Pair a a
instance Functor Pair where
fmap f (Pair a b) = Pair (f a) (f b)
现在,为了证明<代码> FMAPID= ID<代码>,让我们考虑一下<代码> FMAP ID 和<代码> ID >代码>点:
fmap id (Pair a b) = -- by definition
Pair (id a) (id b) = -- by beta reduction
Pair a (id b) = -- by beta reduction
Pair a b
id (Pair a b) = -- by definition
Pair a b
因此,在这种特殊情况下,fmap id=id
然后,您可以检查(尽管技术上已给出上述内容,但您不必检查)是否fmap f。fmap g=fmap(f.g)
所以fmapf。fmap g=fmap(f.g)
现在,你可以把函数合成成一个函子
class Functor f where
fmap :: (a -> b) -> f a -> f b
通过部分应用函数arrow构造函数
注意,a->b
和(>)ab
的意思是一样的,所以当我们说
instance Functor ((->) e) where
fmap的签名专门用于
fmap {- for (->) e -} :: (a -> b) -> (->) e a -> (->) e b
一旦你把箭头翻转过来
fmap {- for (->) e -} :: (a -> b) -> (e -> a) -> e -> b
但这只是函数组合的签名
所以
是一个完全合理的定义,甚至
instance Functor ((->)e) where
fmap = (.)
事实上,它出现在
所以你只需要使用它
import Control.Monad.Instances
您根本不需要编写任何代码来支持这一点,您可以使用fmap
作为函数组合作为特例,例如
fmap (+1) (*2) 3 =
((+1) . (*2)) 3 =
((+1) ((*2) 3)) =
((+1) (3 * 2)) =
3 * 2 + 1 =
7
@超级G:我认为你做不到。如何添加一个函数组合来生成f。g工作?如上所述,这是我想做的一个例子。@Super您似乎看到的是类似于这些定律的东西,它们更多的是文档而不是代码,说明函子应该以某种方式运行。如果没有let,输入“=”,将出现:1:8:parse error。@Super G:您不能在GHCi中定义类或实例。您将得到您所看到的语法错误。您需要在文件中定义它们,然后:在GHCi中加载该文件。当然,您会在代码中遇到各种其他错误,但这是您的根本问题。但是,模式f中的解析错误。g、 它似乎不使用该行来进行函数合成谢谢。再次编辑我的问题。我真的希望这样做。因为我还有其他的定义要尝试。
instance Functor ((->)e) where
fmap = (.)
import Control.Monad.Instances
fmap (+1) (*2) 3 =
((+1) . (*2)) 3 =
((+1) ((*2) 3)) =
((+1) (3 * 2)) =
3 * 2 + 1 =
7