在Haskell中,我可以给一个函数提供太少的参数来取回一个curried函数:
-- the addition function
Prelude> :t (+)
(+) :: Num a => a -> a -> a
-- curried with its first argument => the increment function
Prelude> :t (+) 1
(+) 1 :: Num a => a -> a
-- supplied with both arguments => the result
Prelude> :t (+) 1 2
(+) 1 2 :: Num a => a
但是当我提供太多论据时我会得到什么?
Prelude> :t (+) 1 2 3
(+) 1 2 3 :: (Num a, Num (a -> t)) => t
这是什么,它有名称,对任何东西都有用吗?
答案 0 :(得分:9)
以这种方式思考它是有用的。 总是为函数提供一个参数。 f a b
完全等同于(f a) b
。
所以(+) 1 2 3
与
(((+) 1) 2) 3
现在我们知道((+) 1) 2
是什么,它与(+) 1 2
或1 + 2
只是3相同。所以表达式归结为3 3
。
为什么它不是错误?
Haskell中的整数文字被重载。 3
可以是任何类型,只要此类型具有Num
实例。向函数类型提供Num
实例也没有任何违法行为。类型推断器告诉你:
(Num a, Num (a -> t)) => t
这可以理解为
对于具有
a
实例的任何类型Num
,以及也具有a->t
实例的任何类型Num
,相关表达式的类型为{{1} }。
当然在实践中这样的实例不太可能,但是一个可以原则上定义它们,并使表达式t
评估为明确定义的值。
答案 1 :(得分:5)
一般来说,你只是得到一个错误,因为将一个函数应用到"足够"参数不会产生可以作为函数应用于另一个值的值。
> (++) [1] [2] [3]
<interactive>:1:1: error:
• Couldn't match expected type ‘[Integer] -> t’
with actual type ‘[Integer]’
• The function ‘(++)’ is applied to three arguments,
but its type ‘[Integer] -> [Integer] -> [Integer]’ has only two
In the expression: (++) [1] [2] [3]
In an equation for ‘it’: it = (++) [1] [2] [3]
• Relevant bindings include it :: t (bound at <interactive>:1:1)
但是,对于(+)
,返回值可以是任何类型,其实例为Num
。由于(+) 1 2
的类型为Num a => a
,如果a -> t
也有Num
的实例,则可以假设(+) 1 2
可以再次应用于 void test_func(char* bigarray)
{
std::vector<char> v_data;
int len=strlen(bigarray);
v_data.reserve(len);
v_data.assign(bigarray,bigarray+len);
}
第三个价值。这是一个类型类 open 的演示。