无法匹配预期类型Haskell

时间:2016-03-05 21:13:21

标签: haskell types

我需要列出一个像[B,N,N]这样的案例列表,其列表包含N的索引,如[1,2],以及一个表示最终列表长度的int

这是我的计划:

lignebn :: Int -> [Int] -> [Case]
lignebn i [] = []
lignebn i x 
    | i == last x = [N] : lignebn (i-1) init x -- line 101
    | otherwise = [B] : lignebn (i-1) init x

以下是错误:

devoir.hs:101:17:
    Couldn't match expected type ‘[Int]’ with actual type ‘Int’
    In the first argument of ‘last’, namely ‘(x)’
    In the second argument of ‘(==)’, namely ‘last (x)’

devoir.hs:101:29:
    Couldn't match expected type ‘Int -> [Case]’
                with actual type ‘[Case]’
    The function ‘lignebn’ is applied to three arguments,
    but its type ‘Int -> [Int] -> [Case]’ has only two
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’
    In the expression: [N] ++ lignebn (i - 1) init (x)

devoir.hs:101:43:
    Couldn't match expected type ‘[Int]’
                with actual type ‘[a0] -> [a0]’
    Probable cause: ‘init’ is applied to too few arguments
    In the second argument of ‘lignebn’, namely ‘init’
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’

devoir.hs:102:26:
    Couldn't match expected type ‘Int -> [Case]’
                with actual type ‘[Case]’
    The function ‘lignebn’ is applied to three arguments,
    but its type ‘Int -> [Int] -> [Case]’ has only two
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’
    In the expression: [B] ++ lignebn (i - 1) init (x)

devoir.hs:102:40:
    Couldn't match expected type ‘[Int]’
                with actual type ‘[a1] -> [a1]’
    Probable cause: ‘init’ is applied to too few arguments
    In the second argument of ‘lignebn’, namely ‘init’
    In the second argument of ‘(++)’, namely ‘lignebn (i - 1) init (x)’
Failed, modules loaded: none.

我不明白发生了什么,代码对我来说似乎没问题......

2 个答案:

答案 0 :(得分:1)

last需要一个列表,但您已在模式匹配中将其定义为和Int

lignebn :: Int -> [Int] -> [Case]
lignebn i (x:xs) = ....

意味着

(x:xs)::[Int]

表示x是Int。

在一个不相关的注释中,在Haskell中你不需要在函数调用周围放置parens。不要像last(x)那样拨打电话,而是使用last x。它会起作用,但不是惯用的Haskell。

答案 1 :(得分:1)

在递归调用中,您需要init x周围的括号。实际上,您正在传递init函数和x。您可能还需要NB的列表,而不是列表中的列表,但由于您未包含Case类型的定义,因此很难确定

lignebn :: Int -> [Int] -> [Case]
lignebn i [] = []
lignebn i x 
    | i == last x = N : lignebn (i-1) (init x) -- line 101
    | otherwise = B : lignebn (i-1) (init x)

另请注意,广泛不鼓励使用last等部分功能。更好的是这样的(未经测试):

unsnoc :: [a] -> Maybe ([a], a)
unsnoc [] = Nothing
unsnoc (x : xs) = Just ps where
   ps = case unsnoc xs of
          Nothing -> ([], x)
          Just (~(ys, y)) -> Just (x : ys, y)