我试图理解以下功能:
SELECT
a.Marketplace,
a.ProdID,
a.MktID,
b.Title
FROM
TableA a
INNER JOIN
TableB b ON a.Marketplace = b.Marketplace
AND a.ProdID = b.ProdID
当输入这个:q1(地图abs [-1,-6,-5,7])时,它得到了我5.有人可以告诉我为什么会这样吗?我理解map函数如何,但模式匹配(x:_xs)有点令人困惑。谢谢!
答案 0 :(得分:7)
Haskell中的列表 - 至少在概念上 - 是一个链表。有两种可能性:
[]
;或(x:xs)
其中x
是 head (第一项),xs
tail (列表的其余部分)。 Haskell也使用语法糖。例如,[1]
位于窗帘后面,翻译为(1:[])
,[1,4,2,5]
改为(1:(4:(2:(5:[]))))
。
为什么这很重要?我们首先尝试理解q1
函数。如果我们查看类型,我们会看到q1
将Int
的列表作为输入,并返回Int
。它以递归方式定义为:
q1 :: [Int] -> Int
q1 [] = 0
q1 [x] = x
q1 (x:_:xs) = max x (q1 xs)
这意味着空列表的q1
为零(0
);具有一个元素q1
的列表的x
为x
。对于包含两个或更多元素的列表,该列表maximum
的第一项的x
和该列表的尾部 。这是因为我们将模式与(x:_:xs)
匹配,(x:(_:xs))
是x
的缩写。下划线基本上意味着“不关心”。所以列表应该是 cons ,其中尾部也是 cons ,我们对列表xs
的头部和尾部感兴趣列表的尾部q1
。
如果我们对此进行推理,我们就会发现q1 (map abs [-1,-6,-5,7])
返回奇数索引中元素的最大(所以第一,第三,第五)等元素)。如果列表具有偶数长度,我们还计算最大值为零(因此,如果奇数索引处的所有元素都是负数,则函数将返回零,但此仅> 如果我们有一个甚至长度的列表。
现在,如果用q1
来调用它,则意味着我们会在map abs
上的[-1, -6, -5, 7]
的结果上调用map abs
。 abs
构造一个列表,其中map abs [-1, -6, -5, 7]
应用于列表的所有元素(尽管它是懒惰应用的)。因此,在[1, 6, 5, 7]
之后,我们获得了列表1
。现在奇数索引处的元素是5
和q1
。所以q2 :: (Num a, Ord a) => [a] -> a
q2 [] = 0
q2 [x] = max 0 x
q2 (x:_:xs) = max x (q2 xs)
将计算这些元素的最大值和零(因为列表的长度是4,这是偶数)。 max(0,1,5) 5 。
就个人而言,尤其是我们也认为零而且仅在列表具有偶数长度的情况下,非常“不稳定”。它可能导致难以理解的错误,因为它可能是函数细节的结果。我们可以例如用零计算最大值,无论列表的长度如何:
q3 :: Ord a => [a] -> a
q3 [x] = x
q3 [x,_] = x
q3 (x:_:xs) = max x (q3 xs)
或者我们可以决定不使用零,也不能在空列表中定义最大值,例如:
$galleries = DB::table('galleries')->select( DB::raw('galleries.*') )
->where( 'domain_id', $domain_id )
->where( 'is_deleted', 0 )
->whereNotIn('id', array_keys( Session::get("export_selected" ) ) )
->whereNotIn('id', Session::get("export_skip" ) )
->whereNotIn('id', array_keys( Session::get("export_delete" ) ) )
->whereNotIn('id', array_keys( Session::get("export_delete_all") ) )
->leftJoin('history', function($join) use ( $site_id ) {
$join->where('history.site_id', '=', $site_id )
->on('history.gallery_id', '=', 'galleries.id');
})
->whereNull('history.gallery_id')
->orderByRaw('RAND()')
->take(10)->get();