该功能const在Prelude中定义为:
const x _ = x
Run Code Online (Sandbox Code Playgroud)
在GHCi,当我尝试
Prelude> const 6 5 -> Gives 6
Run Code Online (Sandbox Code Playgroud)
但是当我尝试的时候
Prelude> const id 6 5 -> Gives 5
Run Code Online (Sandbox Code Playgroud)
即使在做出改变之后
Prelude> (const id 6) 5 -> Gives 5
Run Code Online (Sandbox Code Playgroud)
这个函数不应该给出函数6的输出id有id :: a -> a应该绑定的类型
Prelude> (const 6) 5 -> Gives 6
Run Code Online (Sandbox Code Playgroud)
为什么函数const表现不同?
Chu*_*uck 67
你似乎认为这相当于const (id 6) 5,id 6评估为6,但事实并非如此.没有这些括号,你将id函数作为第一个参数传递给const.那么再看看定义const:
const x _ = x
Run Code Online (Sandbox Code Playgroud)
这意味着const id 6 = id.因此,const id 6 5相当于id 5,确实是5.
sno*_*now 14
函数也可以是其他函数的参数.id成为const的参数.
表达式(const id 6)5的作用是:
(const id 6)5
(const id _)5 - 抓住第一个参数id
id 5
五
有关运营商真正做的更多细节:
一对括号中的任何内容都将被视为整个表达式(但并不意味着它将首先计算).例如:(map(1+)),(\ x - >( - )x)
前缀运算符绑定比中缀运算符更强
表达式中最左边的前缀运算符将被视为一个函数,它从左到右抓取表达式中的参数(包括其他前缀运算符),直到面向中缀运算符或行尾.例如,如果在GHCi中键入map(+)id 3 const + 2,您将收到一条错误,上面写着"函数`map'应用于四个参数......"因为map grabs (+),id,3和const作为中缀运算符+之前的参数.
Chuck是对的,Haskell中的函数应用程序是左关联的,这意味着函数调用就像f a b c是等价的(((f a) b) c).请记住,在Haskell中,您应该始终练习查看函数类型,并尝试根据函数类型推断函数可以做什么和不可以做什么.首先,您可能无法从函数类型中推断出任何内容,但是如果有更多经验,则类型信息将变得不可或缺.
是什么类型的const?输入:t constGHCi.它会回来const :: a -> b -> a.a并且b是类型变量,这意味着const将接受任何类型的参数.由于1 日和2 个参数有不同的类型,你可以通过几乎一切功能:
const 1 2 -- returns 1
const 'a' 1 -- returns 'a'
const [1,2,3] "a" -- returns [1,2,3]
Run Code Online (Sandbox Code Playgroud)
可能已经存在类型变量的特定类型类约束const会阻止传递函数,例如Numor Ord,因为函数不是这些类型类的实例.换句话说,函数不表现为数字或有序的东西,所以f + g或f < g没有意义.但const没有类型类约束会阻止我们将函数作为参数传递.还记得Haskell支持高阶函数吗?这意味着Haskell的函数可以接受并返回其他函数.因此:
const (+) (*) -- returns (+)
const head tail -- returns head
const id 2 -- returns id
Run Code Online (Sandbox Code Playgroud)
const只是忽略2 次参数和任何已作为1通过返回第一参数,无论是CHAR,字符串,整数,也许,[],一些非常复杂的代数数据类型,或甚至一个函数.
如果类型const是a -> b -> a,你可以猜到const 'a'没有输入:t const 'a'GHCi 而没有找到它的类型?要找出一个类型的const 'a',替代1个类型ST参数全部到位同一类型的变量,然后从类型的第一个参数.
a -> b -> a:原始类型Char -> b -> Char:在类型变量中替换新类型ab -> Char:通过从类型声明中删除第一个参数的新函数的类型那是什么类型的const id?
a -> b -> a:原始类型(a -> a) -> b -> (a -> a): 代换b -> (a -> a):结果类型(删除第一个参数)b -> a -> a:与上面相同,->运算符是右关联的行使:
const (+),const head,const tail,const (++),const map