Functor中的fmap类型是:
fmap :: Functor f => (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
看起来,首先将函数(a - > b)应用于fa的参数以创建类型b的结果,然后对其应用f,结果为fb
使用Maybe a例如:
fmap show (Just 1)
result is : Just "1"
Run Code Online (Sandbox Code Playgroud)
同说:
Just (show 1)
Run Code Online (Sandbox Code Playgroud)
但是当( - >)用作Functor时(在Control.Monad.Instances中)
import Control.Monad.Instances
(fmap show Just) 1
result is : "Just 1"
Run Code Online (Sandbox Code Playgroud)
也就是说,Just首先应用,然后显示应用.在另一个例子中,结果是相同的:
fmap (*3) (+100) 1
result is 303
Run Code Online (Sandbox Code Playgroud)
为什么不*3先,然后+100?
在下文中,example1是标准语法(如文档所述),Eq a作为约束.在example2,我Eq a直接指定为参数的类型,编译器接受它.但是,我不清楚我可以指定哪种类型的值.对于特定类型a,例如Nat,我假设以某种方式指定Eq Nat默认实现或某些其他命名实现的实现是有意义的.
%default total
example1: Eq a => (x : a) -> (y : a) -> Type
example1 {a} x y = ?example1_rhs
example1b: Eq a => (x : a) -> (y : a) -> Type
example1b {a} x y = x == y = True
example2: (a : Type) -> Eq a -> (x : a) -> (y : a) -> Type
example2 …Run Code Online (Sandbox Code Playgroud) 我昨天问了这个问题,用户@dfeuer 建议我,作为初学者,我不应该定义自己的类。他的评论:
Haskell 初学者根本不应该定义自己的类。学习定义函数、类型和实例。这些是绝大多数实际的 Haskell 代码。当您这样做时,您会很好地了解是什么使某些类真正有用而其他类则不那么有用。您将了解是什么让某些课程易于使用,而其他课程却充满了陷阱。然后,当你找到一个很好的理由来实际定义你自己的类时,你会经历一系列糟糕的类设计,然后你才能做得足够好,只有你的大部分尝试都失败了。设计好的类真的很难,而且很少有必要。
我很好奇,为什么定义我自己的类通常(对于初学者)是个坏主意?这些“陷阱”是什么,为什么设计好的课程如此困难?
我认为类用于定义数据接口,就像我在 OOP 中所做的那样。我在写java代码的时候,尽量用抽象类,尤其是接口来写代码,这样当我需要改变数据的时候,我的大部分代码保持不变,而且我的方法有很高的可重用性。@Carl 在该问题下的另一条评论表明,这不是类的使用方式
你为什么创建这个类?我觉得这很奇怪 - 非常像习惯 OOP 的人会做的事情,而不是习惯 Haskell 的人。它有太多参数,它们以一种非常特别的方式连接起来......
我担心的是,如果没有这种 OOP 使用类,数据的任何更改都会破坏大部分代码。这种恐惧是没有资金的吗?如果它得到资助,为什么我不应该使用类来定义数据接口?
公平地说,我是自学的 Java 程序员,我没有读过别人的代码,所以也许我做的 Java 也错了。我只阅读了一些关于该语言如何工作的书籍,然后构建了一个应用程序。我开发了它一年左右,我的整个风格就是这种体验的结果。不过,我的风格似乎很适合我的需求,因此我认为 Java 编程/OOP 确实是这样完成的。