【问题标题】:Write the recursive function adjuster编写递归函数调整器
【发布时间】:2017-03-18 21:50:40
【问题描述】:

编写递归函数调整器。给定一个类型列表 x,一个 int 和一个 x 类型的元素,要么从前面移除 列出直到它与 int 长度相同,或追加到列表末尾 直到它与 int 指定的值的长度相同。

预期:

adjuster [1..10] (-2) 2 -> *** Exception: Invalid Size
adjuster [1..10] 0 2 -> []
adjuster "apple" 10 ’b’ -> "applebbbbb"
adjuster "apple" 5 ’b’ -> "apple"
adjuster "apple" 2 ’b’ -> "le"
adjuster [] 3 (7,4) -> [(7,4),(7,4),(7,4)]

我做了什么:

adjuster (x:xs) count b 
        | count < 0             = error "Invalid Size"
        | count == 0            = []
        | count < length xs     = adjuster xs (count-1) b
        | otherwise             = (adjuster xs (count-1) b):b

我得到的错误:

 * Occurs check: cannot construct the infinite type: t ~ [t]
      Expected type: [t]
        Actual type: [[t]]
    * In the expression: (adjuster xs (count - 1) b) : b
      In an equation for `adjuster':
          adjuster (x : xs) count b
            | count < 0 = error "Invalid Size"
            | count == 0 = []
            | count < length xs = adjuster xs (count - 1) b
            | otherwise = (adjuster xs (count - 1) b) : b
    * Relevant bindings include
        b :: [[t]] (bound at code01.hs:21:23)
        adjuster :: [a] -> Int -> [[t]] -> [t] (bound at code01.hs:21:1)

我是 haskell 的新手。非常感谢一些帮助。

【问题讨论】:

    标签: haskell recursion functional-programming higher-order-functions


    【解决方案1】:

    您正在尝试在列表中的列表中构造一个列表,依此类推……

    这是为什么?

    (:) :: a -> [a] -> [a]
    

    冒号运算符将一个元素和一个此类元素的列表作为参数,并从中构造一个列表(通过添加该元素)。

    如果(adjuster ...) 具有[a] 类型,则b 必须是[[a]] 类型,第4 行与最终结果相同,但第3 行表示类型为[a] -这是不同的。这就是 GHC 试图告诉你的。

    如何解决?

    首先,向每个顶级函数添加类型签名总是一个好建议:

    adjuster :: [a] -> Int -> a -> [a]
    

    在实现您的功能时,它应该清除您的错误消息并保持诚实。

    那么如何解决这个问题: - 你可以使用 b:adjuster xs (count-1) b 但这会产生错误顺序的结果 - 所以

    选择不同的运算符:(++) 并将b 包装在一个列表中。

        | otherwise             = (adjuster xs (count-1) b)++[b]
    

    现在还有一些提示:

    • 编译文件时打开-Wall - 这将表明您错过了adjuster [] .. 的情况。
    • 使用length 是一项相对昂贵的操作 - 因为它需要遍历要计算的完整列表。
    • 作为练习 - 尝试修改您的函数以不使用length,而仅使用基本情况[] 用于列表和0 用于count(这里函数replicate 可能会有所帮助)。

    【讨论】:

      【解决方案2】:

      这是另一种方法,没有错误处理

      adjuster xs n v = tnr n $ (++) (replicate n v) $ tnr n xs
            where tnr n r = take n $ reverse r
      

      如果你玩签名,也许这样更干净

      adjuster n v = tnr . (++) (replicate n v) . tnr
                   where tnr = take n . reverse
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多