Haskell中的const函数

Rog*_*ews 26 haskell

该功能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的输出idid :: 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.

  • 另一个不错的属性是`const id` =`flip const` (13认同)

sno*_*now 14

函数也可以是其他函数的参数.id成为const的参数.

表达式(const id 6)5的作用是:

(const id 6)5

(const id _)5 - 抓住第一个参数id

id 5

有关运营商真正做的更多细节:

  1. 一对括号中的任何内容都将被视为整个表达式(但并不意味着它将首先计算).例如:(map(1+)),(\ x - >( - )x)

  2. 前缀运算符绑定比中缀运算符更强

  3. 表达式中最左边的前缀运算符将被视为一个函数,它从左到右抓取表达式中的参数(包括其他前缀运算符),直到面向中缀运算符或行尾.例如,如果在GHCi中键入map(+)id 3 const + 2,您将收到一条错误,上面写着"函数`map'应用于四个参数......"因为map grabs (+),id,3const作为中缀运算符+之前的参数.


Mir*_*lov 5

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 + gf < 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,字符串,整数,也许,[],一些非常复杂的代数数据类型,或甚至一个函数.

如果类型consta -> b -> a,你可以猜到const 'a'没有输入:t const 'a'GHCi 而没有找到它的类型?要找出一个类型的const 'a',替代1个类型ST参数全部到位同一类型的变量,然后从类型的第一个参数.

  1. a -> b -> a:原始类型
  2. Char -> b -> Char:在类型变量中替换新类型a
  3. b -> Char:通过从类型声明中删除第一个参数的新函数的类型

那是什么类型的const id

  1. a -> b -> a:原始类型
  2. (a -> a) -> b -> (a -> a): 代换
  3. b -> (a -> a):结果类型(删除第一个参数)
  4. b -> a -> a:与上面相同,->运算符是右关联的

行使:

  1. 揣摩精神上或与笔和纸,不使用GHCI,有什么类型:const (+),const head,const tail,const (++),const map
  2. 试着找出你将传递给上述函数的参数以获得具体的值.