comp shows if two words are lexicographically equal or smaller
import Data.Char
class MyComp a where
comp :: a -> a -> Bool
instance MyComp Char where
comp num1 num2 = (ord num1) <= (ord num2) -- ord :: Char -> Int
instance MyComp a => MyComp [a] where
comp [] _ = True
comp _ [] = False
comp (x:xs) (y:ys)
| comp x y && comp y x = comp xs ys
| comp x y = True
| otherwise = False
上面的代码对我来说有点神秘。有人可以向我解释警卫的情况吗?他们为什么要查看comp x y
和comp y x
是否属实。不应该
| comp x y = comp xs ys
| otherwise = False
诀窍?
答案 0 :(得分:2)
Sheets("TABLAK").Select
Sheets.Add
Dim ujfulneve As String
ujfulneve = Sheets("MENU").Range("B2").Value
Sheets(ActiveSheet).Name = ufjulneve
基本上是一个扩展的小于或等于函数。
您有疑问的代码是将类型comp
中的小于或等于的定义扩展为类型a
。它通过传统的词典排序定义来实现这一点。
现在,由于[a]
和MyComp
之间没有正式关系,因此您无法真正询问Eq
- 而是询问x == y
和{{}的唯一方式根据{{1}},{1}}是相等的,你会在那里进行双重测试。
这个双重测试是为了处理这种情况:
x
现在,这应该是错误的,因为y
应该在comp
之前排序。但要做到这一点,你需要检查超出第一个字母。这就是你要问的代码正在做什么 - 它是在初始字母相等的情况下检查第二个(和后续)字母。
但是你并不总是检查后续的字母!那个案子怎么样:
"abcd" `comp` "aacd"
显然,即使"aacd"
为真且"abcd"
为假,也应如此。
答案 1 :(得分:1)
从MyComp
的定义可以看出,comp x y
等同于x <= y
。现在,定义instance MyComp a => MyComp [a]
意味着如果为类型a
的值定义了小于或等于的关系,那么它也为类型[a]
的值定义,大概使用lexicographical order。
字典顺序的工作方式是,如果要比较两个列表,首先要比较第一个列表的第一个元素和第二个列表的第一个元素。如果它们不同,那么您将使用该比较的结果作为两个列表的比较结果。如果另一方面它们是相等的,那么你看两个列表中的第二个元素,依此类推。这就是上面的代码尝试做的事情:comp x y && comp y x
就像说x <= y && y <= x
,这相当于说x
等于y
。如果发生了。然后根据字典顺序,你必须丢弃这两个元素并查看两个列表的其余部分。