GHC有一个类型系统扩展的整个动物园:多参数类型类,功能依赖,秩n多态,存在类型,GADT,类型族,范围类型变量等等.哪些可能是最容易学习的?另外,这些功能是否以某种方式组合在一起,或者它们是否完全相同,可用于完全不同的目的?
所以,我想手动证明Maybe applicative的组成法则是:
u <*> (v <*> w) = pure (.) <*> u <*> v <*> w
Run Code Online (Sandbox Code Playgroud)
我用这些步骤证明了这一点:
u <*> (v <*> w) [Left hand side of the law]
= (Just f) <*> (v <*> w) [Assume u ~ Just f]
= fmap f (v <*> w)
= fmap f (Just g <*> w) [Assume v ~ Just g]
= fmap f (fmap g w)
= fmap (f . g) w
pure (.) <*> u <*> v <*> w [Right hand …Run Code Online (Sandbox Code Playgroud) 我想将一个函数应用于列表中的每个第二个元素:
> mapToEverySecond (*2) [1..10]
[1,4,3,8,5,12,7,16,9,20]
Run Code Online (Sandbox Code Playgroud)
我写了以下函数:
mapToEverySecond :: (a -> a) -> [a] -> [a]
mapToEverySecond f l = map (\(i,x) -> if odd i then f x else x) $ zip [0..] l
Run Code Online (Sandbox Code Playgroud)
这有效,但我想知道是否有更惯用的方法来做这样的事情.
unsafeVacuous在Data.Void.Unsafe与.#和#.在Data.Profunctor.Unsafe两个警告有关使用这些函数与函子/是GADTs profunctors的危险.一些危险的例子很明显:
data Foo a where
P :: a -> Foo a
Q :: Foo Void
instance Functor Foo where
fmap f (P x) = P (f x)
fmap f Q = P (f undefined)
Run Code Online (Sandbox Code Playgroud)
这里,unsafeVacuous Q将生成Q一个伪造类型的构造函数.
这个例子并不是很麻烦,因为它看起来并不像一个合理的Functor实例.有例子吗?特别是,当仅使用他们的公共API进行操作时,是否有可能构建遵循functor/profunctor法则的有用的那些,但面对这些不安全的函数可能会破坏性?
在Parallella上的GHCi 7.10.2下,我定义了一个Peg派生的数据类型Show.当我试图压缩两个Peg列表时,我遇到了分段错误.有人有任何线索吗?
sid@linaro-nano:~CIS192/hw_2$ ghci
GHCi, version 7.10.2: http://haskell.org/ghc/ :? for help
Prelude>
Prelude>
Prelude> data Peg = Red | Green deriving (Show)
Prelude> zip [Red, Red] [Green, Green]
[(Red,Green),(Segmentation fault
Run Code Online (Sandbox Code Playgroud) 可以将类与镜头混合以模拟重载的记录字段,直到某一点.例如,makeFields参见Control.Lens.TH.我试图弄清楚是否有一种很好的方法可以为某些类型重复使用相同的名称作为镜头,并为其他类型重用遍历.值得注意的是,考虑到产品的总和,每种产品都可以具有透镜,这将降低到总和的遍历.我能想到的最简单的事情就是**:
class Boo booey where
type Con booey :: (* -> *) -> Constraint
boo :: forall f . Con booey f => (Int -> f Int) -> booey -> f booey
Run Code Online (Sandbox Code Playgroud)
这适用于简单的事情,比如
data Boop = Boop Int Char
instance Boo Boop where
type Con Boop = Functor
boo f (Boop i c) = (\i' -> Boop i' c) <$> f i
Run Code Online (Sandbox Code Playgroud)
但是,只要你需要更复杂的东西,它就会落在脸上
instance Boo boopy => Boo (Maybe boopy) where …Run Code Online (Sandbox Code Playgroud) 我想表示一个高达120位的字符串,速度至关重要.我需要能够通过重复snoc操作构建一个位串,然后通过重复操作来消耗它uncons.一个想法是窃取Word128from 的实现data-dword并使用这样的东西来构建:
empty = 1
snoc xs x = (xs `shiftL` 1) .|. x
Run Code Online (Sandbox Code Playgroud)
但是,在countLeadingZeros通过移位和屏蔽高位来读取元素之前,不必要的东西似乎变得有点难看,不得不首先向左移动以消除它们.
是否有一些更愉快的方式,至少同样快,或更快的方式,不是太不愉快?
Phil Ruffwind提出了一个版本的lens's atfor Data.Map,但到目前为止所有的实现都比lens当前密钥比较便宜时使用的天真实现要慢得多.如果我可以在查找条目时生成一个非常便宜的条目路径表示,然后使用专门版本的insert或者非常有效地使用它delete,那么也许我可以使这个值得.
我想得到以下示例进行类型检查:
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Foo where
f :: Int -> (forall f. Functor f => Secret f) -> Int
f x _ = x
g :: (forall f. Functor f => Secret f) -> Int
g = f 4
type family Secret (f :: * -> *) :: * where
Secret f = Int
Run Code Online (Sandbox Code Playgroud)
我得知它可能无法推断和检查gs类型(即使在这种特定情况下它很明显,因为它只是一个部分应用程序):Secret不是单射的,并且没有办法告诉编译器Functor它应该期望哪个实例.因此,它失败并显示以下错误消息:
• Could not deduce (Functor …Run Code Online (Sandbox Code Playgroud) 我目前正在和Hutton教授的"Haskell编程"一起学习Haskell,我发现了一些奇怪的关于Maybe的定义作为Applicative类的一个实例.
在GHC.Base,实例Applicative Maybe定义如下:
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
Run Code Online (Sandbox Code Playgroud)
这是定义的值线Nothing <\*> _作为Nothing困扰我.Nothing是类型Maybe a,操作符<*>实际上需要f (a -> b)(在这种情况下Maybe (a -> b))作为其第一个参数的类型.因此,这是一种类型不匹配,Haskell应该抱怨.但是,这被接受为默认定义,因此Haskell不会在我认为应该的地方抱怨它.
我错过了什么?
我一直致力于在linear-baseSjoerd Visscher 开始的一些工作的基础上添加对泛型派生的支持。一般来说,泛型的性能可以达到预期的效果,但我遇到了递归类型(如列表)的问题,我不知道该怎么办。最简单的例子就是类Consumable。如果你不熟悉线性类型的东西,不要被它迷惑;这在这里几乎无关紧要。我们有
class Consumable a where
-- Read this as consume :: a -> (), but it's guaranteed to use
-- its argument exactly once.
consume :: a %1 -> ()
instance (Generic a, GConsumable (Rep a)) => Consumable (Generically a) where
consume (Generically x) = genericConsume x
genericConsume :: (Generic a, GConsumable (Rep a)) => a %1 -> ()
genericConsume = gconsume . from
{-# INLINEABLE genericConsume #-}
-- | A class for generic …Run Code Online (Sandbox Code Playgroud) haskell ×10
applicative ×2
haskell-lens ×2
types ×2
dictionary ×1
fold ×1
generics ×1
ghc ×1
list ×1
optimization ×1
system-f ×1
traversal ×1
typeclass ×1