SML中的Pig拉丁函数(运算符和操作数错误)

SML中的Pig拉丁函数(运算符和操作数错误),sml,smlnj,Sml,Smlnj,我正在使用Ullman(M97)第二版中的问题练习sml。我目前正在处理的问题是调用一个piglatin函数,该函数接收一个单词,分解它,并检查第一个字符是否是元音(a,e,I,o u)。如果是元音,它会将字符列表内爆回字符串,并在末尾添加“yay”。如果第一个字符不是元音,则函数将检查其余字符,直到遇到第一个元音为止。当它这样做时,它会将第一个元音之前的所有字符放在字符列表的末尾,将新的字符列表内爆回一个字符串,并在其中添加“ay” 例如: - pl "able"; val it = "abl

我正在使用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

我不知道如何修复它。

这是因为
的类型是元音
charlist->bool

如果您查看
aL

fun aL (h::hs) = if isVowel(h) = true then h :: hs
                 else aL (cycle (h :: hs));
is元音(h)
意味着
h
必须是
char list
,这反过来意味着
aL
必须具有类型
char list->char list
,而
内爆(alx)
是一个错误

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

fun isVowel c = ...
然后在
plx

中写
isvowell(hdx)
,你会觉得很有趣。甚至还有一个练习。:-)

爆炸、分析和内爆是很常见的,但效率不高,在某些情况下也不容易。正如molbdnilo所指出的,
is元音
应该接受
char
作为输入,而不是
char列表

fun isVowel c =
    c = #"a" orelse
    c = #"e" orelse
    c = #"i" orelse
    c = #"o" orelse
    c = #"u"
对于将单词转换为拉丁语的函数,完全可以使用字符串函数:

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
现在,有一些极端情况:

  • 如果单词是空的
    ,该怎么办

  • 如果单词是大写的“Ant”
,该怎么办

这两个问题需要解决,以使基于字符串的
piglatin
函数健壮且全面


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

  • 如果P为真,则不写
    ,否则写Q
    ;写
    P或Q
  • 不要写
    Is元音c=true
    ;写
    是元音c
  • aL
    plx
    不是最好的函数名;除了充当
    pl
    cycle
    之间的粘合剂、
    是元音
    爆炸
    内爆
    之外,我不确定它们到底应该是什么

哦,好的。我现在明白了。只是好奇,他们的方法是否可以在plx功能中不使用hd x?仅使用模式匹配。
- piglatin "";
! Uncaught exception:
! Subscript
- piglatin "Ant";
> val it = "ntAay" : string