0

I have to implement an example function with following signature:

[[([Char],  a,  b)]] -> (a  ->  b  ->  Char)  ->  ([Char],  b  ->  a  ->  Char)

So I attempt this way:

funcD [[([' '],x,y)]] uFunc0D = ([' '],  uFunc1D)
    where
        uFunc0D x y = ' '   
        uFunc1D y x  = ' '

but, whe I invoke the type of it with

:t funcD

it returns

funcD :: [[([Char], t1, t2)]] -> t -> ([Char], t3 -> t4 -> Char)

Few questions:

  1. Why does it return t for the 2nd argument rather than (a -> b -> Char)?
  2. I passed ' ' for Char and it works, however I want to pass an empty char-arg like '', but it doesn't work.
  3. Why do I get t3 and t4 rather than t1 and t2 in the result signature?

Thanks in advance

Edit: My next try:

funcD1 [[([' '],x,y)]] (uFunc0D x y = ' ' where _ = x y) = ([' '],  uFunc1D)
    where
        uFunc1D y x  = ' '
4

1 回答 1

4
  1. uFunc0D未使用(您使用where具有相同名称的函数隐藏子句中的参数)
  2. ' '表示字符文字,它必须包含一个字符。您可能正在考虑字符串,在这种情况下""是空字符串。
  3. 的参数与uFunc1D输入参数完全无关,因此它们可以自由地成为不同的类型。xy

编辑:

您必须使用表达式中的参数(等号的右侧)才能影响返回类型。您在where子句中的声明引入了uFunc0Dand uFunc1D。声明uFunc0D隐藏了uFunc0D函数参数(左侧)中的绑定,因此即使您要在 rhs 中提及uFunc0D,它也将是您在 where 子句中声明的那个,而不是参数。

编辑2:

这是一个例子,假设你想要一个函数f :: (a -> b) -> a -> Char

一个天真的尝试可能是: f f1 x = ' ',但这将有一个 type f :: a -> b -> Char。因为f1不知道应该是函数的事实(实际上,您可以将其他内容作为 传递f1),并且它接受与第二个参数相同类型的事实也是不知道的。

相反,如果你这样做:f f1 x = ' ' where _ = f1 x,那么类型将是f :: (a -> b) -> a -> Char. 在这种情况下,编译器知道 f1 必须至少采用一个参数(因为您将其应用于参数),并且该参数必须具有第二个参数的类型(因为您将其应用于第二个参数)。

编辑3:

关于haskell 语法的一句话。

函数声明如下所示:f arg1 arg2 = expr

进入的位置arg1arg2是模式。进入expr的是表达式。

如果你看到类似的东西

f x = y
  where y = x + 1

子句前面where是表达式,后面是表达式中可见的声明。记号前的换行符where不重要,上面与f x = y where y = x + 1.

什么是模式?模式允许您将值分解为多个部分,并将这些部分绑定到名称。

x是一种模式,id x = x例如在 中。这意味着x绑定到 的第一个参数idx右侧的不是模式,而是一个表达式,其值为x,受左侧模式的约束。

(a, b)是另一种模式,如fst (a, b) = a. 此模式规定输入类型应为 2 元组,第一个元素绑定到a,第二个绑定到b

In mkPair a b = (a, b),(a, b)是一个表达式,而不是一个模式。它是一个表达式,具有 2 元组的值,其第一个元素是a(绑定为左侧的第一个参数)和第二个值b(绑定为右侧的第二个参数)。

函数的参数位置总是模式,模式可能看起来像表达式,但它们不是!某段代码是表达式还是模式取决于它相对于其他所有内容的出现位置,而不是它的外观。

于 2013-05-22T00:52:51.513 回答