Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 单子的结合性_Haskell - Fatal编程技术网

Haskell 单子的结合性

Haskell 单子的结合性,haskell,Haskell,包含列表的新类型集。 空::设置一个 空=设置[] newtype Set a = Set [a] 函数创建一个集合 sing :: a -> Set a sing x = Set [x] 核查: 左身份: memSet :: (Eq a) => a -> Set a -> Bool memSet _ (Set []) = False memSet x (Set xs) | elem x xs = True | otherwise = False {

包含列表的新类型集。 空::设置一个 空=设置[]

newtype Set a = Set [a]
函数创建一个集合

sing :: a -> Set a
sing x = Set [x]
核查:

左身份:

memSet :: (Eq a) => a -> Set a -> Bool
memSet _ (Set []) = False
memSet x (Set xs)
    | elem x xs = True
    | otherwise = False

{-
makeSet :: (Eq a) => [a] -> Set a
makeSet [] = empty
makeset (x:xs) = union (sing x) (makeSet xs)
-- etc
-- we need the obvious stuff:

union        :: Set a -> Set a -> Set a
unionMult    :: [ Set a ] -> Set a
intersection :: Set a -> Set a -> Set a
subSet       :: Set a -> Set a -> Bool
mapSet       :: (a -> b) -> Set a -> Set b
mapset f (Set xs) = makeSet (map f xs)
-}

-- now making it a monad:
instance Monad Set where
   return = sing
   (Set x) >>= f =  unionMult (map f x)
权利身份:

return a >>= f ≡ f a
结合性:

 m >>= return ≡ m
左:

 (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
对:

return x >>= f
(Set [x]) >>= f
unionMult (map f [x])
unionMult [ (f x) ] = f x

最后一个需要帮助

unionConcat已在Data.Set…中定义。。。。具体来说,我将在这个证明中使用以下定义

(Set [xs]) >>= return
unionMult (map return [xs])
unionMult [ys]
Set [xs]
(我将使用数据中定义的其他函数。在这里设置,一些函数可能需要“Ord a”,这大概不会是一个问题)

我还利用了以下属性

unionConcat = Data.Set.unions
return = Data.Set.fromList [a]
第一种说法是,两个集合的并集可以通过获取集合中的项目列表,将它们浓缩,然后删除重复项来实现。。。。这源于集合的定义

第二个属性只是声明concat和map(:[])是彼此的反比。从concat的定义来看,这也是显而易见的

union x y = fromList (toList x ++ toList y)
concat . map (:[]) = id
(为了真正完成这个证明,我必须证明这些属性遵循(:[])的Haskell定义,concat和union,但这是我认为您需要的更多细节,实际定义可能会随着版本的不同而变化,因此我们只能假设这些函数的编写者遵循了set和concat应该如何工作的精神)

(如果不明显,请记住monkey操作符(:[])将单个元素包装在括号中-(:[])x=[x])

由于“unions”只是“union”的一个多重应用,“concat”只是(++)的一个多重应用,因此第一个属性可以推广到

map (:[]) [a, b, c, ....] = [[a], [b], [c], ....]
concat [[a], [b], [c], ....] = [a, b, c, ....]
现在是证据-

unions sets = fromList (concat $ map toLists sets)
量化宽松


编辑-见下面的讨论,我犯了一个错误,证明了错误的定律(哦,我应该读一下问题的标题:),所以我在下面添加了正确的一个(结合性)

两个证明结合性,我们需要使用两个属性

y >>= return 
= unions $ map return (toList y)
= unions $ map (fromList . (:[])) (toList y)
= unions $ map fromList $ map (:[]) (toList y)
= unions $ map fromList $ map (:[]) $ toList y
= fromList $ concat $ map toList $ map fromList $ map (:[]) (toList y)
= fromList $ concat $ map (:[]) (toList y)
= fromList $ toList y
= y
其中su排序并统一列表,即-

property 1 - toList (x >>= f) = su (toList x >>=' toList . f)
property 2 - su (x >>=' f) = su (su x >>=' f)
>>='是数组绑定运算符

su [4,2,4,1] = [1,2,4], 
第一个属性应该是显而易见的。。。。它只是说明,您可以通过两种不同的方式获得x>>=f的结果,一种是将f应用于集合x中的值并取并集,另一种是应用于相应列表中完全相同的值,并将这些值合并。唯一的问题是,您可能会在列表中获得重复值(集合甚至不允许),因此您可以应用右侧的su函数来规范化结果(请注意,toList也以相同的形式输出)

第二个属性表示,如果在绑定管道的末尾对结果进行排序/uniq,也可以在管道中更早地执行该操作,而无需更改答案。同样,这应该是显而易见的。。。。添加/删除重复项或使用初始列表重新排序值仅添加/删除重复项或重新排序最终结果。但是,我们将删除重复项并在最后重新排序,所以这并不重要

(根据map/concat、toList等的定义,可以对这两个属性给出更严格的证明,但这会扩大这篇文章的规模……我假设每个人的直觉都足够强大,并继续……)

使用这些,我现在可以给你看证据。一般计划是使用数组绑定操作符的已知关联性,以及数组与集合的关系来表明集合绑定操作符也必须是关联的

x >>=' f = concat . map f x 
暗示

toList set1 == toList set2
我可以证明

set1 == set2
以获得期望的结果

toList ((y >>= f) >>= g) = toList (y >>= (\x -> f x >>= g))

QED

unionConcat已在Data.Set…中定义。。。。具体来说,我将在这个证明中使用以下定义

(Set [xs]) >>= return
unionMult (map return [xs])
unionMult [ys]
Set [xs]
(我将使用数据中定义的其他函数。在这里设置,一些函数可能需要“Ord a”,这大概不会是一个问题)

我还利用了以下属性

unionConcat = Data.Set.unions
return = Data.Set.fromList [a]
第一种说法是,两个集合的并集可以通过获取集合中的项目列表,将它们浓缩,然后删除重复项来实现。。。。这源于集合的定义

第二个属性只是声明concat和map(:[])是彼此的反比。从concat的定义来看,这也是显而易见的

union x y = fromList (toList x ++ toList y)
concat . map (:[]) = id
(为了真正完成这个证明,我必须证明这些属性遵循(:[])的Haskell定义,concat和union,但这是我认为您需要的更多细节,实际定义可能会随着版本的不同而变化,因此我们只能假设这些函数的编写者遵循了set和concat应该如何工作的精神)

(如果不明显,请记住monkey操作符(:[])将单个元素包装在括号中-(:[])x=[x])

由于“unions”只是“union”的一个多重应用,“concat”只是(++)的一个多重应用,因此第一个属性可以推广到

map (:[]) [a, b, c, ....] = [[a], [b], [c], ....]
concat [[a], [b], [c], ....] = [a, b, c, ....]
现在是证据-

unions sets = fromList (concat $ map toLists sets)
量化宽松


编辑-见下面的讨论,我犯了一个错误,证明了错误的定律(哦,我应该读一下问题的标题:),所以我在下面添加了正确的一个(结合性)

两个证明结合性,我们需要使用两个属性

y >>= return 
= unions $ map return (toList y)
= unions $ map (fromList . (:[])) (toList y)
= unions $ map fromList $ map (:[]) (toList y)
= unions $ map fromList $ map (:[]) $ toList y
= fromList $ concat $ map toList $ map fromList $ map (:[]) (toList y)
= fromList $ concat $ map (:[]) (toList y)
= fromList $ toList y
= y
其中su排序并统一列表,即-

property 1 - toList (x >>= f) = su (toList x >>=' toList . f)
property 2 - su (x >>=' f) = su (su x >>=' f)
>>='是数组绑定运算符

su [4,2,4,1] = [1,2,4], 
第一个属性应该是显而易见的。。。。它只是说明,您可以通过两种不同的方式获得x>>=f的结果,一种是将f应用于集合x中的值并取并集,另一种是应用于相应列表中完全相同的值,并将这些值合并。唯一的问题是,您可能会在列表中获得重复值(集合甚至不允许),因此您可以应用右侧的su函数来规范化结果(请注意,toList也以相同的形式输出)

第二个属性表示,如果在绑定管道的末尾对结果进行排序/uniq,也可以在管道中更早地执行该操作,而无需更改答案。同样,这应该是显而易见的。。。。添加/删除重复项或重新排序