Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中实现字符串连接函数_Haskell - Fatal编程技术网

在Haskell中实现字符串连接函数

在Haskell中实现字符串连接函数,haskell,Haskell,我是Haskell的新手,尝试实现一个函数,该函数使用分隔符和列表返回串联字符串(类似于Python中的连接函数) 当我调用这个函数时,strJoin“|”[“foo”,“bar”]它会打印“foo | bar”,即使我希望结果是读“foo | bar” 如何调整模式匹配代码,使其对最后一个元素的工作方式不同?解决方案的问题是,第二个模式也将元素与一个元素匹配(在这种情况下,xs是[]),因此您将有一个额外的递归调用 strJoin sep arr = case arr of [] ->

我是Haskell的新手,尝试实现一个函数,该函数使用分隔符和列表返回串联字符串(类似于Python中的连接函数)

当我调用这个函数时,
strJoin“|”[“foo”,“bar”]
它会打印
“foo | bar”
,即使我希望结果是读
“foo | bar”


如何调整模式匹配代码,使其对最后一个元素的工作方式不同?

解决方案的问题是,第二个模式也将元素与一个元素匹配(在这种情况下,
xs
[]
),因此您将有一个额外的递归调用

strJoin sep arr = case arr of
  [] -> ""
  ([x]) -> x   
  (x : xs) -> x ++ sep ++ strJoin sep xs
如果您不想自己为学习目的构建此应用程序,
Data.List
具有
interlate
用于此目的:


或者您可以同时使用
concat
interspose

问题在于代码的最后一行:

(x : xs) -> x ++ sep ++ strJoin sep xs
模式
x:xs
的含义是
x
将与单个元素匹配,即列表的第一个元素,
xs
将与列表匹配,即除第一个元素外的所有元素的列表。此列表可以为空。具体而言,如果
arr
包含单个元素,则
x
将与该单个元素匹配,
xs
将与列表的其余部分(即空列表)匹配。但在右手边,你实际上有:

x ++ sep ++ strJoin sep []
这相当于

x ++ sep ++ ""
这反过来又与

x ++ sep
这解释了函数的行为。那么我们如何解决这个问题呢?一种解决方案是尝试更改这种情况下的模式,以便不在包含单个元素的列表中使用该规则。一种方法是:

(x : xs @ (_ : _)) -> x ++ sep ++ strJoin sep xs
此处
xs@(:)
将与非空列表匹配。我将把这一解释留作练习。 所以现在,正如我们所希望的,该规则将不会用于单元素列表,但问题是,对于这样的列表,已经没有规则了。所以我们需要添加一个新的。以下步骤可以:

[x] -> x
因此,把所有这些放在一起:

strJoin sep arr = case arr of
    [] -> ""
    (x : xs @ (_ : _)) -> x ++ sep ++ strJoin sep xs
    [x] -> x
当然,还有很多其他方法可以做到这一点,这里有一个:

strJoin sep arr = case arr of
    [] -> ""
    [x] -> x
    (x : xs) -> x ++ sep ++ strJoin sep xs

我将把它作为一个练习来练习它是如何工作的。

谢谢你的回答。我很想知道这是否可以通过模式匹配来实现。我为您添加了一个答案。@MichaelKohl感谢您添加了一个使用模式匹配的解决方案。我把雷德内布的解决方案标记为答案,因为他补充了所有的解释。再次感谢您告诉我有关插入函数的信息。我在谷歌上搜索了数据源。列表和插入函数()并意识到它的实现与我在这里收到的答案非常相似:-)我认为上述原因导致了strJoin“|”[“foo”]=“foo |”,我认为这不是预期的输出。基本情况应该是1,而不是2,IMO。谢谢你回答这个问题。我第一次看到@,我将找到它如何工作的解释。顺便说一句,您的第二个解决方案更具可读性。
strJoin sep arr = case arr of
    [] -> ""
    (x : xs @ (_ : _)) -> x ++ sep ++ strJoin sep xs
    [x] -> x
strJoin sep arr = case arr of
    [] -> ""
    [x] -> x
    (x : xs) -> x ++ sep ++ strJoin sep xs