模式和构造函数之间的"主要"区别是什么?
回答:
With a constructor you can add a tag to your data, in such a way that it receives a type.
Patters will be more used for matching data with a pattern, which isn't the case of a constructor.
Patters can also be used for the destruction reasons.
Run Code Online (Sandbox Code Playgroud)
正如Daniel Fisher所说,构造函数构建了一些价值,模式将它分开:
data Person = P String String Int
-- constructor to build a value
makePerson firstname lastname age = P firstname lastname age
-- pattern to take a value apart
fullName (P firstname lastname _) = firstname ++ " " + lastname
Run Code Online (Sandbox Code Playgroud)
请注意,这只是一个示例,对于此特定类型,记录语法更合适.
在某种意义上,它们彼此非常相似,因为它们是双重的.构造函数可以被认为是数据类型的签名函子的代数,并且在同一仿函数上构造了余代数.
更明确一点,让我们考虑一下[].它的签名函子是T_A X = 1 + A * X或者,在Haskell中
type ListF a x = Maybe (a, x)
Run Code Online (Sandbox Code Playgroud)
有明显的Functor例子.我们可以看到 - ListF带List载波的-algebras 只是它的构造函数
-- general definition
type Algebra f a = f a -> a
consList :: Algebra (ListF a) [a]
consList Nothing = []
consList (Just (a, as)) = a:as
Run Code Online (Sandbox Code Playgroud)
双重,我们可以看看的余代数ListF与List作为其载体
type Coalgebra f a = a -> f a
unconsList :: Coalgebra (ListF a) [a]
unconsList [] = Nothing
unconsList (a:as) = Just (a, as)
Run Code Online (Sandbox Code Playgroud)
并进一步看到安全版本head和tail非常自然的析构函数[]
headMay :: [a] -> Maybe a
headMay = fmap fst . unconsList
tailMay :: [a] -> Maybe a
tailMay = fmap snd . unconsList
Run Code Online (Sandbox Code Playgroud)
这激发了个人的烦恼head,tail甚至没有特别好的功能,忽视了他们的偏见 - 他们只是在具有签名仿函数的无限列表中很自然T A X = A*X.
现在在Haskell 中,一个仿函数的初始Algebra和最后Coalgebra一致作为该仿函数的定点
newtype Fix f = Fix { unfix :: f (Fix f) }
Run Code Online (Sandbox Code Playgroud)
这正是数据类型.我们可以证明它[a]是同构的Fix (ListF a)
fwd :: [a] -> Fix (ListF a)
fwd [] = Fix Nothing
fwd (a:as) = Fix (Just (a, fwd as))
bwd :: Fix (ListF a) -> [a]
bwd (Fix Nothing) = []
bwd (Fix (Just (a, fixed))) = a : bwd fixed
Run Code Online (Sandbox Code Playgroud)
这提供了将数据类型本身用作构造函数和模式的理由,但是如果您创建其他类型的"类似代数"的东西,那么您可以拥有一流的模式,例如由She或模式组合器提供的模式.
为了更深入地理解模式和构造函数的二元性,请尝试使用类似的数据类型再次执行此练习
data Tree a = Leaf | Branch (Tree a) a (Tree a)
Run Code Online (Sandbox Code Playgroud)
它的标志性函子是T A X = 1 + X*A*X或
type TreeF a x = Maybe (x,a,x)
Run Code Online (Sandbox Code Playgroud)