【问题标题】:Polymorphic type of functions as parameter in haskell?多态类型的函数作为haskell中的参数?
【发布时间】:2018-01-14 02:25:58
【问题描述】:

我正在尝试定义以下函数的多态类型:

flip f x y = f y x

我的想法如下:

  1. flip 的第一个参数,f 接受两个参数,所以(t1 -> t2 -> t3)

  2. flip 的第二个参数,x 的类型为 t1,因为参数 t1 f 函数内部。

  3. flip 的第三个参数,yt3 类型,因为参数 t3 > f 函数内部。

  4. 不知道整体返回的多态类型。

但是当我检查 ghci 中的类型时,我得到:

flip :: (t2 -> t1 -> t) -> t1 -> t2 -> t

有人可以帮忙看看这个例子是什么吗?

谢谢

【问题讨论】:

  • 这显然是在翻转你提供给它的函数的参数,该函数采用 t2t1 类型的函数,方法是返回采用 t1t2 类型的相同函数按顺序..

标签: function haskell types polymorphism polymorphic-functions


【解决方案1】:

您的第二个假设是错误的

flip的第二个参数,x的类型是t1,因为f函数内部有参数t1。

我们先来分析一下函数:

flip f x y = f y x

我们看到flip 在头部有三个参数。所以我们先做类型:

flip :: a -> (b -> (c -> d))

当然,我们现在的目标是填写类型。与:

f :: a
x :: b
y :: c
flip f x y :: d

我们在右手边看到:

(f y) x

这意味着f 是一个将y 作为输入的函数。这意味着ac -> e 的类型相同(或更短的a ~ c -> e)。

那么现在:

flip :: (c -> e) -> (b -> (c -> d))
f :: (c -> e)
x :: b
y :: c

此外,我们看到:

(f x) y

所以(f x) 的结果是另一个函数,输入为y。所以这意味着e ~ b -> f。因此:

flip :: (c -> (b -> f)) -> (b -> (c -> d))
f :: c -> (b -> f)
x :: b
y :: c

最后我们看到(f y) xflip f x y 的结果。这意味着(f y) x 的结果类型与d 的类型相同。这意味着f ~ d。这意味着:

flip :: (c -> (b -> d)) -> (b -> (c -> d))

或者如果我们去掉一些多余的括号:

flip :: (c -> b -> d) -> b -> c -> d

【讨论】:

  • 在右手边,你是如何确定 f 只取 y 的?如(f y) x?我想在右手边,它的形式是f (y x)
  • @James:这就是 Haskell 语法的工作原理。如果你写foo bar qux foobar,你就隐式写了((foo bar) qux) foobar...请注意,在Haskell中每个函数只接受一个参数
【解决方案2】:

这只是求解方程组的问题。首先,分配未知类型:

f : a1
x : a2
y : a3

接下来,f 应用于y。所以,f 必须是一个函数类型,其参数类型与 y 相同,即

f : a1 = a3 -> a4
f y : a4

类似地,f y 应用于x,所以

f y : a4 = a2 -> a5
f y x : a5

代入这个,我们得到

f : a3 -> a2 -> a5
x : a2
y : a3

我们可以重命名这些类型

t2 = a3
t1 = a2
t  = a5

得到

f : t2 -> t1 -> t
x : t1
y : t2

函数体为f y x,类型为t = a5

【讨论】:

  • 你是如何确定 f 只接受 y 作为参数的?我以为f拿了f (y x)
  • f y x(f y) x,而不是 f (y x)。在整个 Haskell 中都是如此,而不是特定于这个函数。
  • amalloy 说了什么。另外,如果您不知道诀窍:只要函数是一流的,就可以只使用一个参数函数对任何 n 参数函数进行建模 - 您可以将它们作为结果返回。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多