小编J. *_*son的帖子

标准的Haskell类型类有哪些法则可以维护?

众所周知,Monad实例应该遵循Monad法则.可能不太为人所知,Functor实例应遵循Functor法则.尽管如此,我仍然对编写优化的GHC重写规则感到相当自信fmap id == id.

还有哪些标准类有隐含法则?是否(==)有一个真正的等价关系?是否Ord必须形成部分订单?总订单?我们至少可以假设它是可传递的吗?反对称?

这些最后几个似乎没有在Haskell 2010报告中指定,也不会有信心编写利用它们的重写规则.但是,有没有共同的图书馆?一个实例的病理如何可以自信地写出来?

最后,假设这样一个实例可能存在一个边界,那么每种类型实例必须遵守的法律是否有一个标准的综合资源?


举个例子,我要定义多少麻烦

newtype Doh = Doh Bool
instance Eq Doh where a == (Doh b) = b
Run Code Online (Sandbox Code Playgroud)

它只是难以理解或编译器在任何地方都不正确地优化?

haskell interface proof

9
推荐指数
1
解决办法
799
查看次数

从DataKinds中检索信息约束存在类型

如果我有一个受限制的类型 DataKind

{-# LANGUAGE DataKinds #-}

data K = A | B

data Ty (a :: K) = Ty { ... }
Run Code Online (Sandbox Code Playgroud)

和存在类型忘记了类型中的确切选择K...但是在传递的字典中记住它.

class AK (t :: K) where k :: Ty t -> K
instance AK A where k _ = A
instance AK B where k _ = B

data ATy where ATy :: AK a => Ty a -> ATy
Run Code Online (Sandbox Code Playgroud)

真的是这样的情况ATy <-> Either (Ty A) (Ty B),但如果我想写一个我需要使用的证人unsafeCoerce

getATy :: ATy -> Either …
Run Code Online (Sandbox Code Playgroud)

haskell existential-type data-kinds

9
推荐指数
1
解决办法
220
查看次数

为什么'ZonedTime'没有'Eq'或'Ord'实例

time包装我们有型ZonedTime,其代表了LocalTime一个产品localDay :: DaylocalTimeOfDay :: TimeOfDay.LocalTime有实例为EqOrd,但ZonedTime不会.在我看来,ZonedTime应该从绝对参考框架进行比较,至少与LocalTimes可能相比.

为什么不ZonedTimeEqOrd实例呢?

值得注意的是,time重写thyme实际上确实有EqOrd实例,但我不想使用非标准时间类型,除非需要.

time haskell

8
推荐指数
1
解决办法
257
查看次数

GHC部分评估和单独编译

MLton这样的整个程序编译器创建了优化的二进制文件,部分原因是它们能够使用二进制文件的总来源来执行部分评估:积极地内联常量并在编译期间对它们进行评估直到卡住全部!

Gabriel Gonzalez的Morte在Haskell空间中对此进行了公开的探讨.

现在我的理解是,Haskell并没有做很多这方面 - 如果有的话.我理解的原因是它与分离编译是对立的.这对于禁止跨源文件边界进行部分评估是有意义的,但似乎文件内部分评估仍然是一种选择.

据我所知,仍未执行文件内部分评估.

我的问题是:这是真的吗?如果是这样,执行文件内部分评估的权衡是什么?如果没有,什么是一个示例文件,通过将更多功能放入同一个文件,可以提高编译性能?

(编辑:为了澄清上述内容,我知道有很多问题需要执行哪些最佳减少 - 很多都是不可判定的!我想知道在"工业强度"编译器中做出的权衡取舍如果有任何有趣的事情可以在那里讨论,那么生成在选择正确的等式理论的水平上的编译.编译速度或文件膨胀等问题更多地涉及我感兴趣的范围.同一空间中的另一个问题可能是: "为什么MLton不能通过单独编译每个模块来获得单独的编译,让API暴露,然后将它们全部链接在一起?")

compiler-construction haskell ghc compiler-optimization

8
推荐指数
1
解决办法
308
查看次数

如何检查单纯形是否包含原点?

我正在实施Gilbert-Johnson-Keerthi算法,该算法计算两个物体是否相交(即碰撞).

我的代码的入口点是hasCollided函数,它接受两个点列表并True在它们相交时返回.我相信我已经正确地实现了论文 - 但是,我仍然需要实现这个contains功能.

contains函数应确定单纯形是否包含原点.我不确定如何实现这一点.

如何有效地确定单形(点集合)是否包含原点?


以下是我的实施:

type Simplex = Set (Vector Double)

hasCollided :: [Vector Double] -> [Vector Double] -> Bool
hasCollided points1 points2 = gjk points1 points2 simplex (scale (-1) direction) p
  where simplex   = insert p empty
        p         = support points1 points2 direction
        direction = fromList [1, 0, 0]

gjk :: [Vector Double] -> [Vector Double] -> Simplex -> Vector Double -> Vector Double -> Bool
gjk …
Run Code Online (Sandbox Code Playgroud)

math haskell physics linear-algebra collision

7
推荐指数
2
解决办法
1704
查看次数

是否有"纯粹适用的Either"的标准名称或实施?

我经常找我称之为"纯粹的应用性使用Either",即EitherApplicative,只要我们没有实现一个可用实例Monad的实例,以及.

newtype AEither e a = AEither { unAEither :: Either e a }
  deriving Functor

-- technically we only need Semigroup
instance Monoid e => Applicative (AEither e) where
  pure a = AEither (pure a)
  AEither e1 <*> AEither e2 = AEither (combine e1 e2) where
    combine (Right f) (Right a) = Right (f a)
    combine (Left m1) (Left m2) = Left (m1 <> m2)
    combine (Left m ) _         = …
Run Code Online (Sandbox Code Playgroud)

haskell either applicative

7
推荐指数
1
解决办法
173
查看次数

如何使用(或不使用)Oasis创建多级模块层次结构

假设我有一组模块,每个模块都与子模块相当"浓密".

M1.X        M2.X        M3.X
M1.Y        M2.Y        M3.Y
M1.Z        M2.Z        M3.Z
M1.W        M2.W        M3.W
M1.Q        M2.Q        M3.Q
M1.P        M2.P        M3.P
Run Code Online (Sandbox Code Playgroud)

此外,我希望每个灌木丛都能放在一个主模块下面.

Home.M1
Home.M2
Home.M3
Run Code Online (Sandbox Code Playgroud)

现在,很容易构建项目目录为每个M1,M2以及M3使用绿洲Pack:选项.特别是,我喜欢和想要解决的是(a)能够以标准.ml/ .mli格式布置我的文件和(b)ocamldoc生成正确链接的文档.

但因为我想分配每个M1,M2以及M3在一个共同的模块层次结构下的同一个库,我不能用Pack:和我,而不是被迫扔掉整个该死的东西到一个文件中,以(一)不小心揍全球命名空间,(b)不会意外地扩散Home.名称空间中不打算直接使用的模块,以及(c)不破坏ocamldoc链接.

所以我的问题是,根据上面提出的目标,我如何使用Oasis创建一个包含这种形式的分层模块的包?

一些额外的限制包括:

  • 这并非偶然,根据模块M1.,M2.M3.命名空间冲突---这发生在真实的情况,以及!
  • 在模块M2.M3.命名空间取决于该模块M1.的命名空间.

我的偏好将能够达到一种解决方案,该解决方案还允许合理的文件布局,例如

src -+
     +-- m1 -+
     |       +-- x.ml
     |       +-- x.mli
     |       +-- y.ml …
Run Code Online (Sandbox Code Playgroud)

ocaml module oasis

7
推荐指数
1
解决办法
537
查看次数

用于广义多参数函数提升的类型类技巧

我想将Haskell函数提升为更高阶的lambda演算编码.这几乎是从Oleg的Typed Tagless Final编码中逐字逐句的.

class Lam r where
  emb :: a -> r a
  (^) :: r (r a -> r a) -> (r a -> r a)
  lam :: (r a -> r a) -> r (r a -> r a)

instance Lam Identity where
  emb   = Identity
  f ^ x = f >>= ($ x)
  lam f = return (f . return =<<) -- call-by-value

 eval = runIdentity
Run Code Online (Sandbox Code Playgroud)

我可以将任意Haskell类型嵌入到Lam使用中emb,但我不能(^)用于应用程序.此外,提升的功能会表现得很懒散.相反,我必须通过应用程序解除它们的应用程序.

emb1 :: ( Applicative …
Run Code Online (Sandbox Code Playgroud)

dsl haskell typeclass lifting

6
推荐指数
1
解决办法
214
查看次数

模块和存在之间的区别

OCaml模块是"仅仅"存在类型的民间知识.两者之间有某种平等

module X = struct type t val x : t end
Run Code Online (Sandbox Code Playgroud)

data 'a spec = { x : 'a }
data x = X : 'a spec
Run Code Online (Sandbox Code Playgroud)

这并非完全不真实.

但正如我刚才所证明的那样,OCaml有模块和存在类型.我的问题是:

  • 他们有什么不同?
  • 有什么可以在一个而不是另一个中实现吗?
  • 你什么时候使用一个(特别是比较一流模块和存在类型)?

ocaml module existential-type

6
推荐指数
2
解决办法
1161
查看次数

在haskell中实现解压缩功能

我正在尝试实现解压缩功能,我做了以下代码但是我收到了错误.

myUnzip [] =()
myUnzip ((a,b):xs) = a:fst (myUnzip xs)  b:snd (myUnzip xs)
Run Code Online (Sandbox Code Playgroud)

我知道问题出在第二行的右侧,但我确实知道如何改进它.任何提示请.

我得到的错误是

ex1.hs:190:22:
Couldn't match expected type `()' with actual type `[a0]'
In the expression: a : fst (myUnzip xs) b : snd (myUnzip xs)
In an equation for `myUnzip':
    myUnzip ((a, b) : xs) = a : fst (myUnzip xs) b : snd (myUnzip xs)


ex1.hs:190:29:
Couldn't match expected type `(t0 -> a0, b0)' with actual type `()'
In the return type of a call of …
Run Code Online (Sandbox Code Playgroud)

haskell

5
推荐指数
2
解决办法
6701
查看次数