Haskell 哈斯克尔:猪拉丁语
问:翻译成“Pig拉丁语”的简单规则是,取一个以元音开头的单词,加上“yay”,同时取任何带有一个或多个辅音的单词,并在后面加上“ay”。例如,“able”变为“ableyay”,而“stripe”变为“IPE”。编写一个函数,将一串字母转换为它的拉丁翻译 实施:Haskell 哈斯克尔:猪拉丁语,haskell,apache-pig,Haskell,Apache Pig,问:翻译成“Pig拉丁语”的简单规则是,取一个以元音开头的单词,加上“yay”,同时取任何带有一个或多个辅音的单词,并在后面加上“ay”。例如,“able”变为“ableyay”,而“stripe”变为“IPE”。编写一个函数,将一串字母转换为它的拉丁翻译 实施: -- define function to detect vowel isVowel :: Char -> Bool isVowel c = elem c ['u','e','o','a','i'] -- define fu
-- define function to detect vowel
isVowel :: Char -> Bool
isVowel c = elem c ['u','e','o','a','i']
-- define function Latin Pig
lp ::String -> String
lp str = if (isVowel (head str)) then do {str ++ "yay"}
else
do {
str ++ (head str)
tail str
lp str
}
问题:到目前为止,我的代码(逻辑)没有任何问题。老实说,这是我的哈斯克尔课程介绍作业。但是,编译器给了我错误:
**Couldn't match expected type `t0 -> t1 -> t2 -> t3 -> [Char]'
with actual type `Char'
Expected type: [t0 -> t1 -> t2 -> t3 -> [Char]]
Actual type: String
In the first argument of `head', namely `str'
In the second argument of `(++)', namely
`(head str) tail str lp str'
Failed, modules loaded: none.**
我的代码怎么了 首先,考虑模式匹配。
任何非空列表都可以定义为x:xs,带有,
x作为主要名单
xs作为尾部列表 然后你的代码变成
-- define function Latin Pig
lp :: String -> String
lp [] = ""
lp (x:xs) = if (isVowel x) then str ++ "yay"
else ..... -- fill here
where str = (x:xs)
不要忘记操作符:是列表的构造函数,例如,“a”:“bab”=>“abab” 请记住,字符串是字符列表。
此外,您可以跳过上一个示例中的where子句,如下所示
-- define function Latin Pig
lp :: String -> String
lp [] = ""
lp str@(x:xs) = if (isVowel x) then str ++ "yay"
else ..... -- fill here
应该足够帮助你了。祝你好运我不确定使用递归是否是你要求的一部分,但以下是我对你的任务的看法。你不需要使用
do
monad来实现你想要的(除非这是作业的目标?)
您可能想考虑使用模式匹配和保护,而不是IF其他块。
此外,正如zurgl所说,您可以利用如下方式匹配字符串:string@(x:xs)
,这将允许您在使用头x
和尾xs
的同时处理整个字符串
注意:所有字符串都是列表
下面是我建议的一个快速示例
-- define function to detect vowel
isNotVowel :: Char -> Bool
isNotVowel c = notElem c ['u','e','o','a','i']
-- define function Latin Pig
lp :: String -> String
lp [] = []
lp p@(x:xs)
| not $ isNotVowel x = p++"yay"
| otherwise = let (constants, rest) = span isNotVowel p
in (rest++constants++"ay")
祝你学习哈斯克尔愉快
学习haskell的一些不错的资源:
- 如果一个单词不是以一系列辅音开头,那么翻译的是原单词,后跟“yay”
- 否则,翻译是单词的其余部分,后面是辅音的首字母,后面是“ay”
您会发现将您的
isVowel
函数与Data.List中的函数结合起来很有帮助。请参考以下代码
private static BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
System.out.print("Enter sentence: ");
String sentence = getString();
String latin = pigLatinForSentence(sentence);
System.out.println(latin);
}
private static String pigLatinForSentence(String s) {
String latin = "";
int i = 0;
while (i < s.length()) {
while (i < s.length() && !isLetter(s.charAt(i))) {
latin = latin + s.charAt(i);
i++;
}
if (i >= s.length())
break;
int begin = i;
while (i < s.length() && isLetter(s.charAt(i))) {
i++;
}
int end = i;
latin = latin + pigWord(s.substring(begin, end));
}
return latin;
}
private static boolean isLetter(char c) {
return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
}
private static String pigWord(String word) {
int split = firstVowelInSentence(word);
return word.substring(split) + "-" + word.substring(0, split) + "ay";
}
private static int firstVowelInSentence(String word) {
word = word.toLowerCase();
for (int i = 0; i < word.length(); i++)
if (word.charAt(i) == 'a' || word.charAt(i) == 'e' || word.charAt(i) == 'i' || word.charAt(i) == 'o'
|| word.charAt(i) == 'u')
return i;
return 0;
}
private static String getString() throws IOException {
return buf.readLine();
}
private static BufferedReader buf=新的BufferedReader(新的InputStreamReader(System.in));
公共静态void main(字符串[]args)引发IOException{
系统输出打印(“输入句子:”);
String语句=getString();
字符串拉丁语=piglatinforecentence(句子);
System.out.println(拉丁语);
}
专用静态字符串pigLatinForSentence(字符串s){
拉丁字符串=”;
int i=0;
而(i=s.length())
打破
int begin=i;
而(i return((c>='A'&&c='A'&&cdo
-表示法是用于单子的,我真的怀疑您是否想在这里使用列表单子。Charlie,我认为您的问题在于您不理解基本的haskell语法。不要只接受一个c程序,对它应用一些基本的转换,并期望结果在haskell中工作。