(* Carsten Schuermann *) (* Set *) let datatype ''a Feature = A of ''a | B of ''a | C of ''a datatype Color = Color datatype Pattern = Pattern datatype Number = Number datatype Shape = Shape type Card = Color Feature * Pattern Feature * Number Feature * Shape Feature fun valid (x: ''a Feature, y:''a Feature, z:''a Feature) = (x = y andalso y = z) orelse (x <> y andalso y <> z andalso x <> z) fun validCard ((c1, p1, n1, s1) : Card, (c2, p2, n2, s2) : Card, (c3, p3, n3, s3) : Card) = valid (c1, c2, c3) andalso valid (p1, p2, p3) andalso valid (n1, n2, n3) andalso valid (s1, s2, s3) val Red = A Color val Green = B Color val Blue = C Color val Full = A Pattern val Half = B Pattern val Plain = C Pattern val One = A Number val Two = B Number val Three = C Number val Oval = A Shape val Wave = B Shape val Box = C Shape val card1 : Card = (Red, Full, Three, Oval) val card2 : Card = (Blue, Full, Three, Oval) val card3 : Card = (Green, Full, Three, Oval) fun enumerateColor k = foldr (fn (x, y) => k x @ y) nil [Red, Blue, Green] fun enumeratePattern k = foldr (fn (x, y) => k x @ y) nil [Full, Half, Plain] fun enumerateNumber k = foldr (fn (x, y) => k x @ y) nil [One, Two, Three] fun enumerateShape k = foldr (fn (x, y) => k x @ y) nil [Oval, Wave, Box] val deck = enumerateColor (fn c => enumeratePattern (fn p => enumerateNumber (fn n => enumerateShape (fn s => [(c, p, n, s)])))) fun enumerateDeck k = foldr (fn (x, y) => k x @ y) nil deck val sample = enumerateDeck (fn x => enumerateDeck (fn y => enumerateDeck (fn z => if x <> y andalso y <> z andalso x <> z then [(x, y, z)] else []))) in foldr (fn (x, (t, f)) => if x then (t+1, f) else (t, f+1)) (0, 0) (map validCard sample) end