abstract:判斷 a 和 b 都在 xx里面 ,或者 c 在 xx 里面當然實際可能不止 3 個元素參與判斷。怎樣用簡潔通用的代碼實現(xiàn)這個邏輯?直接 按照題目上那樣寫雖然不報錯,但是語義卻完全不同In [177]: print (1 and 2) in [1,1,3]FalseIn [178]: print 1 and 22In [179]: print (1 and 2) in [2,3]True這個 (a
判斷 a 和 b 都在 xx里面 ,或者 c 在 xx 里面
當然實際可能不止 3 個元素參與判斷。
怎樣用簡潔通用的代碼實現(xiàn)這個邏輯?
直接 按照題目上那樣寫雖然不報錯,但是語義卻完全不同
In [177]: print (1 and 2) in [1,1,3]
False
In [178]: print 1 and 2
2
In [179]: print (1 and 2) in [2,3]
True
這個 (a and b or c) in cc 一眼看上去類型不太對,先讓我們把它寫的更加 explicit 一些:
in_(or_(and_(contains(a), contains(b)), contains(c), cc)
可以看出,如果上述式子的類型是 Bool,而且 forsome x. a, b, c :: x; cc :: Set x; contains :: x -> Set x -> Bool,那么一個合理的類型推斷是 and_, or_ :: (x -> Bool) -> (x -> Bool) -> x -> Bool; in_ :: forall x. x -> x。
正如 F91 所說,類型清楚之后,剩下的就是填空了。我們先用 Haskell 寫一遍:
contains x = foldr combine False where combine x' r = x' == x || r-- Control.Concatenative-- 也可以寫成 bi f g h = h <$> f <*> gbi f g h x = f x `h` g xand_ f g = bi f g (&&)or_ f g = bi f g (||)main = print x where x = (contains 1 `and_` contains 2 `or_` contains 3) [1, 3, 5]
寫成 Python 就是
import operatordef contains(x): def call(xs): return x in xs return calldef bi(f, g, h): def call(x): return h(f(x), g(x)) return calldef and_(f, g): return bi(f, g, operator.and_)def or_(f, g): return bi(f, g, operator.or_)print(or_(and_(contains(1), contains(2)), contains(3))([1, 3, 5]))