我编写了一个程序,其目的是用指数本身替换/扩展给定单词中的每个辅音字符,' o'和遵循的遵循。如果角色是人声,程序应该忽略它并继续前进。
例如,字符串" progp"应该导致" poprorogogpop"。字符串中唯一的声音" progp"是' o' o因此不应重复。 这基本上意味着我想构建一个用String替换char的程序。
这是我到目前为止所做的:
rovarsprak :: String -> String --Definition of our function which recieves an String as input and returns a String--
isVocal :: Char -> String --Function which determines if a letter is a vocal or not--
vocals = ["aeiouy"]; --List with relevant vocals--
rovarsprak [] = []; --Case for empty input--
rovarsprak (x:xs) = isVocal(x) ++ rovarsprak(xs)
isVocal x = if elem [x] vocals
then [x]
else [x] ++ "o" ++ [x]
如果我使用输入参数编译并运行它" progp"我收到了:
" poprorooogogpop"
输出中的所有内容都是正确的,直到' o' " progp"中的句子中间的字符因为声乐' o'不应该以这种方式重复。
我怀疑错误在if语句的elem部分内,或者它可能与递归有关。
通知,我对haskell编程极为陌生,并且已经搜索了与elem-statement相关的问题,但没有成功。
答案 0 :(得分:1)
您的代码中有2个错误。首先,String已经是一个字符列表,因此vocals = "aeiouy"
就足够了。
然后你可以测试elem x vocals
。
此外,循环函数rovarsprak
不是尾递归。 foldl
将通过在签名中处理累加器来实现这一点(并且它也更清楚它是一个循环):
rovarsprakBis :: String -> String
rovarsprakBis = foldl (\acc x -> acc ++ isVocal x) ""
答案 1 :(得分:1)
vocals
旨在成为String
,而不是[String]
:
vocals = "aeiouy" --List ['a','e','i','o','u','y'] with relevant vocals--
isVocal
如果返回Bool
则会是一个好名字;你实际上正在返回一个可能不同的字符串,所以像consonantToSyllable
这样的东西会更好。
请注意,只返回正确的字母列表而不是构建一堆短列表并将它们连接起来更简单。
consonantToSyllable x = if elem x vocals then [x] else [x,'o',x]
或
consonantToSyllable x | elem x vocals = [x]
| otherwise = [x,'o',x]
rovarsprak [] = []
rovarsprak (x:xs) = consonantToSyllable x ++ rovarsprak xs
上面的递归是concatMap
捕获的模式:在列表上映射函数,然后将结果列表连接成一个列表。
rovarsprak word = concatMap consonantToSyllable word
或只是
rovarsprak = concatMap consonantToSyllable