基本问题:在选择使用类或使用记录(具有多态字段)时,应该遵循哪些设计原则?
首先,我们知道类和记录本质上是等价的(因为在Core中,类被去掉了字典,这只是记录).然而,存在差异:类是隐式传递的,记录必须是显式的.
更深入一点,在以下情况下,课程非常有用:
当我们(仅参数多态)只有一个数据表示时,类很尴尬,但我们有多个实例.如果我们不想打开各种麻烦的扩展(即,我们知道这些标记在运行时被删除),这导致了必须使用newtype添加额外标记(仅存在于我们的代码中,因为我们知道此类标记在运行时被删除)的语法噪音(即重叠和/或不可判定的实例).
当然,事情变得更加混乱:如果我想对我的类型有限制怎么办?让我们选一个真实的例子:
class (Bounded i, Enum i) => Partition a i where
index :: a -> i
Run Code Online (Sandbox Code Playgroud)
我可以很容易地完成
data Partition a i = Partition { index :: a -> i}
Run Code Online (Sandbox Code Playgroud)
但现在我已经失去了约束,我将不得不将它们添加到特定的功能中.
是否有设计指南可以帮助我?
我已经广泛搜索了,虽然我可以找到很多cabal文件的例子以及很好的教程,但我希望对.cabal文件格式有一个正确的语法定义.唉,我一直都找不到.最近的cabal文档仅提到它的文件格式是向后兼容的 - 没有链接到它与之兼容的'原始'格式!没有用.
它似乎是流行的编程语言文化中的"被接受的概念","C是便携式汇编程序".我至少15年前第一次听到这个消息.但什么时候它真的成为流行文化的一部分?
注意:如果您不同意'C是便携式汇编程序',请跳过此问题.这个问题是关于"流行的编程文化".我会在这个问题上添加评论,你可以对那些不同意该陈述的人进行投票.
这是一个简单的示例,其中标识Functor运行良好:
newtype R a = R a
instance Functor R where
fmap f (R a) = R $ f a
Run Code Online (Sandbox Code Playgroud)
但如果我添加一个中间类型的家庭,事情会变得很糟糕:
data IntT
data a :-> b
type family Sem a :: *
type instance Sem IntT = Int
type instance Sem (a :-> b) = Sem a -> Sem b
newtype S a = S (Sem a)
Run Code Online (Sandbox Code Playgroud)
现在我无法将S变成Functor.我可以很容易地定义一类类似类似Functor的东西,但是我还需要一类类似Applicative和Monad的东西,这似乎是一条不愉快的道路.特别是
smap f (S a) = S $ f a
Run Code Online (Sandbox Code Playgroud)
实际上有我想要的类型,即smap :: (Sem a -> Sem b) -> S a -> …
所有关于如何对Haskell包进行cabal化的教程和示例都假设该包具有单个作者(以及单个维护者).如何正确归功于.cabal文件中的多个作者?
我可能遗漏了一些基本的东西.
我可以证明以下"身份":
Theorem identity_simple : forall a : Prop, a -> a.
Run Code Online (Sandbox Code Playgroud)
随着intro. intro. assumption.
.
但是,我似乎无法证明:
Theorem identity : forall a : Prop, a.
Run Code Online (Sandbox Code Playgroud)
我当然能做到intro
,但这让我:
a : Prop
_________(1/1)
a
Run Code Online (Sandbox Code Playgroud)
我不知道该怎么做.
第一种形式似乎是多余的,表明对所有人而言a
,a
意味着a
.