2016-09-18 46 views
1

超级基本问题 - 但我似乎无法得到明确的答案。下面的函数将无法编译:基本的Haskell函数类型?

randomfunc :: a -> a -> b 
randomfunc e1 e2 
    | e1 > 2 && e2 > 2  = "Both greater" 
    | otherwise    = "Not both greater" 

main = do 
    let x = randomfunc 2 1 
    putStrLn $ show x 

我很困惑,为什么这不起作用。这两个参数都是类型'a'(Ints),返回参数是类型'b'(字符串)?

错误:

"Couldn't match expected type ‘b’ with actual type ‘[Char]’" 

回答

7

不完全。您的函数签名指示:对于所有类型ab,如果给出a类型的两件事,randomfunc将返回b类型的东西。

但是,randomFunc返回String[Char])。而且,由于你比较e12对方,你不能使用所有a的,只有那些能与>使用:

(>) :: Ord a => a -> a -> Bool 

注意e1 > 2也需要一种方式来创建这样一个从a2

(> 2) :: (Num a, Ord a) => a -> Bool 

因此,无论使用特定类型的,或者确保你正确地处理所有这些约束条件:

randomfunc :: Int -> Int -> String 

randomFunc :: (Ord a, Num a) => a -> a -> String 
2

Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?

在Haskell的类型签名,当你编写与作为a小写字母开头这样的名字,编译器隐式添加forall a.到类型的开头。所以,这就是编译器实际看到:

randomfunc :: forall a b. a -> a -> b 

类型签名声称你的函数会因任何(“所有”)类型ab呼叫者抛出在你的工作。但是这不适用于你的功能,因为它只能分别在IntString上运行。

你需要让你的类型更加具体:

randomfunc :: Int -> Int -> String 

在另一方面,也许你打算要求编译器自动填写您ab,而不是声称,它会工作全部为ab。在这种情况下,您真正​​需要的是PartialTypeSignatures功能:

{-# LANGUAGE PartialTypeSignatures #-} 

randomfunc :: _a -> _a -> _b