haskell - Haskell 中的递归

标签 haskell recursion

我仍在学习 Haskell,我正在做一些练习,但我遇到了麻烦。所以我有一个名为“novel”的函数,它接受 2 个字符串和一个 Int (novel::(String, String, Int) -> String) 作为参数。 Novel 的输入/输出必须如下所示:

> novel ("Rowling", "Harry Potter", 1998)
"Harry Potter (Rowling, 1998)"

这是我的新功能代码,其工作原理如上所述:

novel :: (String, String, Int) -> String
novel (author, book, year) = book ++ " (" ++ author ++ ", " ++ (show year) ++ ")" 

我正在尝试编写一个名为“cite”的新函数(cite::[(String, String, Int)] -> String)。 Cite 的输入/输出应如下所示:

> cite [("author1", "book1", year1), ("author2", "book2", year2), ("author3", "book3", year3)]
"book1 (author1, year1)
book2 (author2, year2)
book3 (author3, year3)"

我正在尝试递归地使用“新颖的”,以获得所需的输出,但我不确定如何去做。

我尝试过的:

cite :: [(String, String, Int)] -> String                -- | Listed arguments
cite [] = ""                                             -- | Base Case
cite x:xs = [(novel (author, book, year)), (novel (author, book, year)), (novel (author, book, year))]

老实说,这是我所了解的。显然,它不起作用,但我不确定从这里开始做什么。

最佳答案

也许这会给你一个良好的开端:

cite :: [(String, String, Int)] -> String
cite [] = ""
cite (x:xs) = undefined -- put your code that recursively calls cite in here, hint: use ++ and "\n\"

模式匹配 (x:xs) 是这样说的,给我列表中的第一项 x 和列表的尾部 xs。这和写这个是一样的:

cite xs' = let x = head xs'
               xs = tail xs'
           in  undefined -- your code here

甚至

cite xs' = undefined -- your code here
    where
        x = head xs'
        xs = tail xs'

希望这有助于将您推向正确的方向。

编辑:OP 询问如何递归执行此操作,以下是我的原始答案:

您可能应该重写您的基本案例以说 cite [] = ""。它并没有真正的区别,但它有助于提高代码的可读性。

让我们先将“:t map novel”放入ghci,看看会得到什么:

> :t map novel
map novel :: [([Char], [Char], Int)] -> [[Char]]

我们可以重写为:map novel::[(String, String, Int)] -> [String]

如何?因为 map 将一种类型 a 转换为另一种类型 b 并将其应用于列表中的每个项目。 map 的第一个参数是任何接受一个参数的函数。正是 novel 所做的。

但这并没有给我们你所需要的,我们最终会得到一个字符串列表而不是一个字符串:

> cite [("author1", "book1", year1), ("author2", "book2", year2), ("author3", "book3", year3)]
["book1 (author1, year1)","book2 (author2, year2)","book3 (author3, year3)"]

您希望它是一个由换行符“\n”分隔的字符串。是否有一个函数可以接受一个字符串列表并将它们连接成一个字符串,但在它们之间插入一个分隔符?

首先让我们描述这样一个函数:String -> [String] -> String。接下来我们将它放入 Hoogle 以查看我们得到了什么:https://www.haskell.org/hoogle/?hoogle=String+-%3E+%5BString%5D+-%3E+String

啊,第二个函数 intercalate 听起来正是我们需要的。它不仅适用于字符串,它适用于任何列表。它是如何工作的?像这样:

> import Data.List (intercalate)
> intercalate "\n" ["List","Of","Strings"]
"List\nOf\nStrings"

所以现在您可以结合使用 intercalate 和 map 来获得您想要的结果。 cite 的定义由您决定。

编辑:完全忘记了,实际上有一个专门的功能。如果你只是在 Hoogle 中搜索 [String] -> String 你会发现 unlines

关于haskell - Haskell 中的递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27883944/

相关文章:

haskell - 为什么 Haskell 中的 seq 必须对底部有特殊的规则?

haskell - GetOpt - 2. ArgDescr 的参数?

haskell - 箭在行动的最先进的例子?

c - 递归删除字符串中的重复字符

pointers - golang return [] * TreeNode {}和return [] * TreeNode {nil}有什么区别

haskell - 如何从列表中选择每个第 n 个元素

haskell - Eq1/Ord1 类型类的目的和语义

python - [[...]] 在 python 中是什么意思?

javascript - 如何每 60 秒调用一次 JavaScript 函数?

Haskell迷宫求解算法