哈斯克爾不能做這樣的儘管有些語言可以像CLIPS或F#那樣使用active patterns。
但是我們可以使用Haskell現有的模式匹配功能來獲得相似的結果。讓我們先來定義這樣定義的函數調用解構:
deconstruct :: [a] -> [([a], a, [a])]
deconstruct [] = []
deconstruct [x] = [([], x, [])]
deconstruct (x:xs) = ([], x, xs) : [(x:ys1, y, ys2) | (ys1, y, ys2) <- deconstruct xs]
什麼這個函數是獲得一個列表XS的所有分解成形式(ys1, y, ys2)
這樣ys1 ++ [y] ++ ys2 == xs
的三倍。因此,例如:
deconstruct [1..4] => [([],1,[2,3,4]),([1],2,[3,4]),([1,2],3,[4]),([1,2,3],4,[])]
利用這一點,你可以按照如下定義功能:
checkNotSameScope xs n e = BoolLit $ not $ any (alreadyThere n) prefixes
where
prefixes = do
(xs, ("$", Undefined), _) <- deconstruct xs
return xs
:
checkNotSameScope xs n e =
case [ys | (ys, ("$", Undefined), _) <- deconstruct xs] of
[ys] -> BoolLit $ not $ alreadyThere n xs
_ -> -- handle the case when ("$", Undefined) doesn't occur at all or more than once
我們可以使用do-notation獲得的東西更接近你在找什麼
這裏有幾件事情正在進行。首先prefixes
變量將存儲在("$", Undefined)
對之前出現的所有前綴列表 - 如果該對不在輸入列表xs
中,則該變量將不存在。然後使用any函數我們正在檢查alreadyThere n
是否給我們任何前綴的True。剩下的就是完成你的函數的邏輯。
也許我應該問,「我怎樣才能做到這一點沒有模式匹配的另一種方式,因爲這是不可能的?」哈斯克爾是非常聰明的人。 – nicole