【问题标题】:Function with a -> a -> a possible in Haskell?在 Haskell 中使用 a -> a -> a 可能的函数?
【发布时间】:2017-11-13 05:59:20
【问题描述】:

我正在阅读 Haskell 编程书和第 140 页的练习,作者指出:

A hypothetical function a->a->a has two possible implementations. Write both possible versions.

我假设a -> a -> a 将暗示一个带有两个参数(a and a) 的函数-(这对我来说没有意义,如果我将一个带有两个参数的函数声明为a,ghci 也正确地抱怨)并返回a

我想我错过了什么,是什么?

【问题讨论】:

  • 你能发布完整的练习描述吗?
  • a 可能表示一个类型;没有约束,它是一种你一无所知的类型,这将你限制在两个具有签名a -> a -> a 的实现中。 (我不是 Haskell 程序员,但我想我知道问题的所在。)
  • 用外行的话来说:因为你需要知道关于参数类型的一些东西才能对它做任何事情,你不能对任何一个参数做任何事情。由于您无法对任一参数执行任何操作,因此您可以返回(未更改的)参数一或参数二。
  • @Ngm 函数的每个参数都需要有不同的名称。 a -> a -> a 的类型签名只是说前两个参数具有相同的类型。这并不意味着它们具有相同的名称。
  • 它们的名称不同,它们的类型相同。 a -> a -> a 表示该函数接受两个相同类型的参数类型 a 并返回相同类型的值。

标签: haskell


【解决方案1】:

思考这个问题的方法也许是想象一下我们对你的论点有多少不了解aa

例如,我们不可能这样说:

someFunc :: a -> a -> a
someFunc x y = x == y

这不会进行类型检查,因为我们甚至不知道a 是否是类型类Eq 的一个实例。换句话说,我们没有关于这些a 事物的有用信息,除了它们是同一类型的事物(不管是什么)。

考虑恒等函数:

ident :: a -> a
ident x = ...

对于它的唯一参数x,这个函数一无所知。因此,只有一个可能的有效结果:

ident x = x

没有其他方法有效,因为我们无法对我们的论点做出任何其他假设。

现在,在您的情况下,您有两个参数,它们绝对可以是宇宙中的任何东西。对于这两个论点可以符合的任何行为,我们无法做出任何断言。因此,我们可以用两种不同的方式定义我们的函数:

someFunc1 :: a -> a -> a
someFunc1 x y = x

someFunc2 :: a -> a -> a
someFunc2 x y = y

没有其他有效的方式来表示这个函数。

【讨论】:

  • 事实上ident 有第二种可能的实现方式:ident x = ident x。或等效的ident x = y where y = y(或等效的... where y = undefined)。 --- (实际上,你的意思是把你的第二个someFunc1 称为someFunc2 吗?)
  • 您在这两个帐户上都是对的。对于第二点,我试图制作一个可编译的示例并进行区分。
【解决方案2】:

f :: a -> a -> a,因为a的类型没有限制,唯一可能的2个实现就是返回第一个/第二个参数,即

f x _ = x

f _ x = x

【讨论】:

    猜你喜欢
    • 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
    相关资源
    最近更新 更多