【问题标题】:Pig latin function in SML (Operator and Operand error)SML 中的 Pig latin 函数(运算符和操作数错误)
【发布时间】:2019-04-19 07:13:46
【问题描述】:

我正在使用 Ullman(M97) 第二版中的问题练习 sml。我目前正在处理的问题需要一个 piglatin 函数,它接收一个单词,分解它,并检查第一个字符是否是元音(a、e、i、o u)。如果它是元音,它会将字符列表内爆回字符串并在末尾添加“yay”。如果第一个字符不是元音,则该函数将检查其余字符,直到遇到第一个元音。当它这样做时,它将所有出现在第一个元音之前的字符放在字符列表的末尾,将新的字符列表内爆成一个字符串并在其中添加“ay”。

例如:

- pl "able";
val it = "ableyay" : string

- pl "stripe";
val it = "ipestray" : string

fun isVowel (c::cs) = 
    if c = #"a" then true
    else if c = #"e" then true
    else if c = #"i" then true
    else if c = #"o" then true
    else if c = #"u" then true
    else false

fun cycle nil = nil
  | cycle (h :: hs) = hs @ [h]

fun aL (h::hs) =
    if isVowel(h) = true
    then h :: hs
    else aL (cycle (h :: hs))

fun plx (x) =
    if isVowel x = true
    then (implode x) ^ "yay"
    else implode (aL (x)) ^ "ay"

fun pl (x) =  plx (explode x)

我已经解决了大部分问题,但我不知道为什么我的 plx 函数给了我这个:

Error: operator and operand don't agree [tycon mismatch]  
operator domain: char list list  
operand:         char list 
in expression: aL x uncaught exception Error

我不知道如何解决它。

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    因为isVowel的类型是char list -> bool

    如果你看aL

    fun aL (h::hs) = if isVowel(h) = true then h :: hs
                     else aL (cycle (h :: hs));
    

    isVowel(h) 意味着h 必须是char list,这又意味着aL 必须具有char list list -> char list list 类型,而implode (aL x) 是一个错误。

    要修复,请将isVowel 更改为char -> bool

    fun isVowel c = ...
    

    并将isVowel (hd x) 写入plx

    【讨论】:

    • 哦,好的。我现在明白了。只是好奇他们是否可以在不使用 plx 函数中的 hd x 的情况下做到这一点?仅使用模式匹配。
    【解决方案2】:

    那时您可能会觉得Exercism's SML track 很有趣。甚至还有Pig Latin 练习。 :-)

    爆炸、分析和内爆很常见,但效率不高,在某些情况下也不容易。正如 molbdnilo 指出的那样,isVowel 可能应该接受char 作为输入而不是char list

    fun isVowel c =
        c = #"a" orelse
        c = #"e" orelse
        c = #"i" orelse
        c = #"o" orelse
        c = #"u"
    

    对于将单词转换为pig latin的函数,您可以完全使用字符串函数:

    fun piglatin (word : string) =
        let val firstLetter = String.sub (word, 0)
        in if isVowel firstLetter
           then word ^ "yay"
           else String.extract (word, 1, NONE) ^ str firstLetter ^ "ay"
        end
    

    对此进行测试:

    - piglatin "pig";
    > val it = "igpay" : string
    
    - piglatin "ant";
    > val it = "antyay" : string
    

    现在,有一些极端情况:

    • 如果这个词是空的""怎么办?

      - piglatin "";
      ! Uncaught exception:
      ! Subscript
      
    • 如果单词是大写的"Ant"怎么办?

      - piglatin "Ant";
      > val it = "ntAay" : string
      

    需要解决这两个问题才能使基于字符串的piglatin 函数健壮total


    以下是对您发布的解决方案的一些反馈:

    • 不要写if P then true else Q;写P orelse Q
    • 不要写isVowel c = true;写isVowel c
    • aLplx 不是最好的函数名;除了在plcycleisVowelexplodeimplode 之间充当胶水,我不确定它们到底应该做什么。

    【讨论】:

      猜你喜欢
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 2018-09-27
      • 1970-01-01
      相关资源
      最近更新 更多