Haskell 哈斯克尔:猪拉丁语

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

问:翻译成“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 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的一些不错的资源:


这里是另一种表达pig拉丁语规则的方式:

  • 如果一个单词不是以一系列辅音开头,那么翻译的是原单词,后跟“yay”
  • 否则,翻译是单词的其余部分,后面是辅音的首字母,后面是“ay”
这更容易翻译成Haskell

(实际Haskell代码被省略,因为这是家庭作业。)


您会发现将您的
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;
而(ireturn((c>='A'&&c='A'&&c
do
-表示法是用于单子的,我真的怀疑您是否想在这里使用列表单子。Charlie,我认为您的问题在于您不理解基本的haskell语法。不要只接受一个c程序,对它应用一些基本的转换,并期望结果在haskell中工作。