小编J. *_* M.的帖子

尽管种类不同,但类型家庭注入违规

在以下示例中:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE PolyKinds #-}
newtype A a b = A (a, b)
type family F (x :: k) = (r :: k) | r -> x
type instance F (A a) = A a
type instance F (A a b) = A a b
Run Code Online (Sandbox Code Playgroud)

在我目前的理解中,第一个类型实例处理*->*kind,而第二个实例处理*.

因此,即使我使用相同的 newtype A,我也看不到任何注入性违规风险,因为绝对没有A a匹配 a ,A a b因为它们甚至没有相同的类型。

然而 GHC 8.6.5 抱怨这两种类型的实例违反了注入性,但这是为什么呢?有解决方法吗?

haskell type-families type-kinds

7
推荐指数
0
解决办法
152
查看次数

在Haskell中,如何在不同的Traversable之间进行映射?

我们知道,fmap“签名是(a -> b) -> f a -> f b其中f的一个Functor

为了尽可能地通用和更好地分解因子代码,人们可能希望将“事物列表”映射到另一个可能不同的“事物列表”。凭直觉,我不明白为什么它不应该或不可能。

我正在寻找的功能gmap与该功能具有相同的功能,fmap但具有该签名gmap :: (a -> b) -> (f a) -> (g b),在该功能中,我允许到达和离开容器有所不同。

我不确定这在一般情况下where fgare 是否有意义Functors,但是Traversable假设我最感兴趣的是遍历数据,那么“事物列表”的想法在本质上听起来更像是课堂上所捕获的。

所以也许签名应该是gmap :: (Traversable f, Traversable g) => (a -> b) -> (f a) -> (g b)

即使g具有不同的性质f,它仍然可以从左到右遍历,因此仍然觉得应该能够将的第k个被访问元素映射f到的第k个被访问元素g

假设我的想法没有错,Haskell中是否有这样的功能?

从本质上讲,我的问题是,您将如何以最简洁,最优雅的方式从Haskell中的一个类似列表的事物转换为另一个?

haskell traversal functor

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

为什么Data.Vector.Mutable read()由于其不可变的操作而在monad中返回?

在这里查看http://hackage.haskell.org/package/vector-0.12.0.3/docs/Data-Vector-Mutable.html 可以看到读取类型为:

read :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
Run Code Online (Sandbox Code Playgroud)

由于读取操作不会修改向量,所以我的主要问题是为什么不这样做:

read :: PrimMonad m => MVector (PrimState m) a -> Int -> a
Run Code Online (Sandbox Code Playgroud)

可变向量的长度在向量上也做不可变的事情,其类型 MVector s a -> Int看起来很正常。不是PrimMonad m => MVector (PrimState m) a -> m Int。那么,为什么在读取和长度之间做出设计选择上的差异,因为它们都是向量上的不变操作?

现在我考虑一下,以某种方式读取返回的单元格是对向量内部单元格的引用,而不是其数据的副本吗?如果是这样,我怎么能以可变的向量很好且廉价地获得对第n个元素的不变访问?我正在学习haskell,但不太了解细节。

谢谢,

haskell vector

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

在Haskell中,即使启用AllowAmbiguousTypes,为什么类型仍然是模棱两可的?

因此,假设您有两个这样定义的类型类:

{-# LANGUAGE MultiParamTypeClasses #-}

class F a c where f :: a -> c
class G c b where g :: c -> b
Run Code Online (Sandbox Code Playgroud)

然后,您想通过使用f和g以一般方式定义新函数h。

h a = g (f a)
Run Code Online (Sandbox Code Playgroud)

我们知道此函数具有类型,a -> b因此c在其中隐含。我想把它留给的实现者f以及可能是g什么c。Haskell抱怨这句话c含糊不清。

然后根据错误提示,我打开了该扩展名:

{-# LANGUAGE AllowAmbiguousTypes #-}
Run Code Online (Sandbox Code Playgroud)

现在可以了!真好

我相信通常作为一种好的软件工程实践,我想写出我的函数的明确规范,以告诉编译器我期望我的函数应具有的行为。这样以后的编译器就可以抱怨我不尊重我的设置。

因此,我想在其之前添加函数的类型:

h :: (F a c, G c b) => a -> b
h a = g (f a)
Run Code Online (Sandbox Code Playgroud)

现在,类型歧义错误再次出现...为什么?

总结一下为什么Haskell在下面的代码段中会抱怨这一点?即使显式启用了AllowAmbiguousTypes。如何在保留显式函数类型定义的同时对其进行修复?我知道删除该函数的类型定义可以解决该问题,但是我不想对事物进行低估。

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE …
Run Code Online (Sandbox Code Playgroud)

haskell typeclass

4
推荐指数
1
解决办法
109
查看次数

Haskell kind system vs type families and multi param type classes

In Haskell I find it difficult to completely grasp the purpose of a kind system, and what it truly adds to the language.

I understand having kinds adds safety. For example consider fmap :: (a -> b) -> f a -> f b vs a monokinded version of it fmap2 :: (a -> b) -> p -> q.

My understanding is that, thanks to the kind system, I can specify beforehand with higher detail what the shape of the …

haskell type-kinds

4
推荐指数
1
解决办法
241
查看次数

在 Haskell 中,为什么存在类型类层次结构/继承?

为了澄清我的问题,让我以或多或少等效的方式重新表述它:

为什么 Haskell 中有超类/类继承的概念?导致这种设计选择的历史原因是什么?例如,为什么拥有一个没有类层次结构、只有彼此独立的类型类的基础库会如此糟糕?

在这里我将揭露一些让我想问这个问题的随机想法。我目前的直觉可能不准确,因为它们是基于我目前对 Haskell 的理解,这并不完美,但它们在这里......

对我来说,为什么 Haskell 中存在类型类继承并不明显。我觉得这有点奇怪,因为它造成了概念上的不对称。通常在数学中,概念可以从不同的角度来定义,我不一定想赞成如何定义它们的顺序。好吧,证明事物应该有一定的顺序,但是一旦定理和结构存在,我宁愿将它们视为可用的独立工具。

Moreover one perhaps not so good thing I see with class inheritance is this: I think a class instance will silently pick a corresponding superclass instance, which was probably implemented to be the most natural one for that type. Let's consider a Monad viewed as a subclass of Functor. Maybe there could be more than one way to define a Functor on some type that also happens to be a …

haskell typeclass

3
推荐指数
1
解决办法
770
查看次数

在 Haskell 中,对类头或类方法的明确约束?

我最近意识到这一点:

一方面:

在类标头上指定的约束必须在该类的实例上再次指定,但在其他地方将该类用作约束的任何使用都不需要重新导入类约束。他们暗自满意。

class (Ord a) => ClassA a where methodA :: a -> Bool -- i decided to put constraint (Ord a) in the class header
instance (Ord a) => ClassA a where methodA x = x <= x   -- compiler forces me to add (Ord a) => in the front
Run Code Online (Sandbox Code Playgroud)
class OtherClassA a where otherMethodA :: a -> Bool 
instance (ClassA a) => OtherClassA a where otherMethodA x = x <= x && methodA x -- i don't …
Run Code Online (Sandbox Code Playgroud)

haskell constraints typeclass

2
推荐指数
1
解决办法
616
查看次数

在 Haskell 中,如何重新排序多种类型

假设我有一种类型l :: * -> * -> *,所以我需要应用 2 种类型a,并b获得一个简单的类型l a b

如何将类型映射l :: * -> * -> *到新类型m(l) :: * -> * -> *,其中的m(l) b a含义与l a bfor each相同a,b?这里a,b不是常数。是否可以?这么想有错吗?

haskell polykinds

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

在 Haskell 中,如何使用继承的参数显式地为这个特定的子函数签名?

说你有这个功能

import Control.Monad
import Control.Monad.ST
import Data.STRef

f :: (Num a, Ord a) => STRef s a -> ST s ()
f i = loop
        where
            loop = do
                _i <- readSTRef i
                writeSTRef i (_i - 1)
                when (_i > 1) loop
Run Code Online (Sandbox Code Playgroud)

inloop的主体,i被隐式定义,因为它是来自 的参数f。但是我在给loop. Hie 告诉我它应该是ST s (),所以我写loop :: ST s ()了上面loop的定义。

但是 ghc 抱怨它无法将sfromloopsfrom匹配f。由于loop没有参数,它 …

haskell signature

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