我正在玩我在 Haskell 中的第一次非平凡的(在我眼中)嘗試。我可能會詢問有關每個部分的問題,以將我的長期關系與類似 c 語言的嘗試與您作為經驗豐富的功能程式員可能會做的事情進行比較。幸運的是,Haskell 很難依靠直接的 c 到 Haskell 代碼轉換。你必須學會??如何正確地做這件事——我想這樣做。
對于這一部分,我有一個 [2uple] 和一個 2uple。我想知道 2uple 中的任何專案是否在 [2uple] 中的任何專案中。
hasmatch tlst tupm = foldr (\tup acc ->
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
if tmatch tup tupm
then (Just True) -- short out
else acc -- do nothing, keep looping
) Nothing tlst
-- hasmatch [(1,2), (3,4), (5,6)] (5,3) ==> Just True
-- hasmatch [(1,2), (9,4), (7,6)] (5,3) ==> Nothing
我寧愿回傳一個普通的 Bool 但那里沒有什么大不了的。
我敢肯定還有另一種方式,我必須摸索一段時間才能理解。那很好。尋找接盤俠。
謝謝
uj5u.com熱心網友回復:
讓我們從您的代碼開始。
hasmatch tlst tupm =
foldr (\tup acc ->
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
if tmatch tup tupm
then (Just True) -- short out
else acc -- do nothing, keep looping
) Nothing tlst
既然你說你更喜歡布爾結果,我們可以切換到那個。事實上,布林值會更好,因為在上面的代碼中我們從不回傳Just False。
hasmatch tlst tupm =
foldr (\tup acc ->
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
if tmatch tup tupm
then True -- short out
else acc -- do nothing, keep looping
) False tlst
現在,if x then True else y簡直就是x || y。
hasmatch tlst tupm =
foldr (\tup acc ->
let tmatch (a,b) (c,d) = a==c || b==c || a==d || b==d in
tmatch tup tupm || acc
) False tlst
如果您想知道,當我們找到匹配項時||不會評估acc。這與 C 短路的惰性語意相同。與 C 相比,主要區別在于布爾變數acc可以表示未評估的布爾結果,而在 C 中,它始終是完全評估的布林值。
現在,tmatch使用相同的第二個引數 ,tupm因此我們可以行內它,并盡早進行模式匹配:
hasmatch tlst (c,d) =
foldr (\tup acc ->
let tmatch (a,b) = a==c || b==c || a==d || b==d in
tmatch tup || acc
) False tlst
我們甚至可以移動let外部以提高可讀性。
hasmatch tlst (c,d) =
let tmatch (a,b) = a==c || b==c || a==d || b==d
in foldr (\tup acc -> tmatch tup || acc) False tlst
我們也可以在where這里使用:
hasmatch tlst (c,d) = foldr (\tup acc -> tmatch tup || acc) False tlst
where tmatch (a,b) = a==c || b==c || a==d || b==d
最后,我們可以利用一個庫函式:any. 呼叫any p list評估是否True存在list滿足 property 的任何元素p。我們的代碼變成:
hasmatch tlst (c,d) = any tmatch tlst
where tmatch (a,b) = a==c || b==c || a==d || b==d
而已。
請注意,上述方法還有其他選擇。可以將元組[(a,b), (c,d), ...串列轉換為所有組件的串列[a,b,c,d,...,然后使用它。
hasmatch tlst (c,d) = any tmatch [ x | (a,b) <- tlst, x <- [a,b]]
where tmatch x = x==c || x==d
uj5u.com熱心網友回復:
根據 chi 的回答,您最好用這種相等來定義資料型別?
{-# Language DerivingStrategies #-}
{-# Language InstanceSigs #-}
{-# Language StandaloneKindSignatures #-}
import Data.Kind (Type)
type AnyTuple :: Type -> Type
data AnyTuple a = a :×: a
deriving stock Show
instance Eq a => Eq (AnyTuple a) where
(==) :: AnyTuple a -> AnyTuple a -> Bool
a1:×:b1 == a2:×:b2 = or [ x == y | x <- [a1, b1], y <- [a2, b2] ]
那么你尋找的函式是一個標準庫函式,比如elemorfind
>> 5:×:3 `elem` [1:×:2, 3:×:4, 5:×:6]
True
>> 5:×:3 `elem` [1:×:2, 9:×:4, 7:×:6]
False
>> find (== 5:×:3) [1:×:2, 3:×:4, 5:×:6]
Just (3 :×: 4)
>> find (== 5:×:3) [1:×:2, 9:×:4, 7:×:6]
Nothing
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/408312.html
標籤:
上一篇:Excel缺少某些功能
