单可遍历包中的MonoFoldable似乎能够实现所有通常的可折叠容器等等,例如,Bytestring可以制作类似于同类元组的东西,MonoFoldable但不能Foldable.我的问题是,除了需要一些先进的GHC功能之外MonoFoldable,我们是否会丢失任何我们没有的Foldable内容,使得它对于实例编写者来说稍微有些棘手,并且可能会收到更加丑陋的错误消息?
例如,是否有一些代码在使用Foldable编译时但是MonoFoldable没有推断类型?或者其他任何使客户端(不是实例编写器代码)明显更简单的Foldable东西MonoFoldable?
我可以写下面的内容:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ConstraintKinds #-}
f :: Integral a => (forall b. Num b => b) -> a
f = id
Run Code Online (Sandbox Code Playgroud)
一切都很好.据推测GHC可以得到Integral从Num这样一切都很好.
我可以有点琐事,但我仍然很好:
class Integral x => MyIntegral x
instance Integral x => MyIntegral x
class Num x => MyNum x
instance Num x => MyNum x
f' :: MyIntegral a => (forall b. MyNum b => b) -> a
f' = id
Run Code Online (Sandbox Code Playgroud)
所以我想说我想概括一下,如下: …
使用一些扩展,我可以这样做:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
type family TF (a :: Bool) where
TF 'True = Int
TF 'False = Double
data D a where
D :: TF a -> D a
Run Code Online (Sandbox Code Playgroud)
请注意,构造函数D可以以两种方式工作.或者:
D :: Int -> D 'True
Run Code Online (Sandbox Code Playgroud)
要么
D :: Double -> D 'False
Run Code Online (Sandbox Code Playgroud)
使用这种模式,我可以根据它的类型完全改变构造函数的参数,同时重用它的名称.
但是,我也想要依赖它名称的参数数量.
我知道我可以用()或替换一些参数Void但我宁愿完全删除它们.
反正有没有这样做?
有没有办法定义这样的函数:
f :: (C a, C b) => a -> Maybe b
Run Code Online (Sandbox Code Playgroud)
这样:
f = Just
Run Code Online (Sandbox Code Playgroud)
当type a= b,和
f _ = Nothing
Run Code Online (Sandbox Code Playgroud)
当键入a/ = b?
注意:
C,但我很确定它是必要的(特别是如果我想避免重叠实例).Equal a b会使这个问题变得微不足道但是它需要n^2我想要避免的实例.我一直在玩Cloud Haskell.我在hackage文档中注意到有一种应用程序界面.但特别是我正在尝试closurePure使用以下签名查找或编写函数:
closurePure :: (Typeable a, Binary a) => a -> Closure a
Run Code Online (Sandbox Code Playgroud)
这基本上是纯粹的限制版本.
虽然Closure数据类型本身是抽象的,但以下closure提供了:
closure :: Static (ByteString -> a) -> ByteString -> Closure a
Run Code Online (Sandbox Code Playgroud)
所以我可以做到这一点:
closurePure :: (Typeable a, Binary a) => a -> Closure a
closurePure x = closure ??? (encode x)
Run Code Online (Sandbox Code Playgroud)
问题是在什么地方放置???.
我的第一次尝试如下:
myDecode :: (Typeable a, Binary a) => Static (ByteString -> a)
myDecode = staticPtr (static decode)
Run Code Online (Sandbox Code Playgroud)
我发现自己写的是这样的:
data T1
data T2
type Unsatisfiable = T1 ~ T2
Run Code Online (Sandbox Code Playgroud)
所以我可以这样做:
type family NEq t1 t2 :: Constraint where
NEq t t = Unsatisfiable
NEq _ _ = ()
type HasProxyT t = NEq t (ProxyT t)
Run Code Online (Sandbox Code Playgroud)
然后我可以使用HasProxyT限制默认方法不循环如果代理类型与它们自己相同(不会阻止两个实例循环到彼此的默认方法,但你必须非常愚蠢做这样的事情) .
但是定义Unsatisfiable看起来有点难看?是否有更好的定义方式,Unsatisfiable或者这只是它的方式吗?
我正在开发一个代表键/值映射的类,我有一个基本上是这样的函数alterF:
class C t where
...
alterF :: Functor f =>
(Maybe (Value t) -> f (Maybe (Value t))) -> Key t -> t -> f t
Run Code Online (Sandbox Code Playgroud)
不幸的是,这打破了GeneralisedNewtypeDeriving.在某些情况下,这是合理的,因为GeneralisedNewtypeDeriving从我理解的本质上使用Coercible和函数coerce.Coercible表示在表示上相等的类型,即它们在运行时具有相同的表示,因此我们可以在它们之间进行免费转换.例如,给定:
newtype T a = T a
Run Code Online (Sandbox Code Playgroud)
我们有:
Coercible a (T a)
Coercible (T a) a
Run Code Online (Sandbox Code Playgroud)
但我们没有(一般情况下):
Coercible (f a) (f (T a))
Coercible (f (T a)) (f a)
Run Code Online (Sandbox Code Playgroud)
例如,GADT违反了这种代表性的平等.但是有很多值f的确有效.例如:
Coercible (Maybe a) (Maybe (T a))
Coercible (Maybe (T …Run Code Online (Sandbox Code Playgroud) 对于我.NET 2.0正在进行的项目,我很遗憾(我们的许多目标机器仍然是Windows XP),这意味着Nuget的库 不需要任何Optional类型.Optional.NET 3.5
幸运的是,滚动自己的Optional类型非常简单,但我遇到了一个问题.
我想要以下内容:
class Optional<T> : (IComparable<Optional<T>> when T : IComparable<T>)
Run Code Online (Sandbox Code Playgroud)
也就是说,我希望我的Optional类型能够实现Comparable,但只有当底层类型是Comparable.
上面的语法遗憾地无效,但是有没有办法实现我正在寻找的东西?
实际上这个问题并不局限于Optional它,它将适用于任何想要定义的容器类型,它可以实现它的内部类型的接口.
我意识到我可以做到这一点:
class Optional<T>
class ComparableOptional<T> : Optional<T>, Comparable<ComparableOptional<T>>
where T : Comparable<T>
Run Code Online (Sandbox Code Playgroud)
但这似乎有点傻,因为那时我们真的要走下这个兔子洞:
class Optional<T>
class EquatableOptional<T> :
Optional<T>,
IEquatable<EquatableOptional<T>>
where T : IEquatable<T>
class ComparableOptional<T> :
EquatableOptional<T>,
IComparable<ComparableOptional<T>>,
IEquatable<ComparableOptional<T>>
where T : IComparable<T>
Run Code Online (Sandbox Code Playgroud)
此外,如果T是Enumerable,Optional<T>也可以Enumerable(如果没有值则返回一个空的枚举器),那么我们就有了更多的类.
由于 …
I'm starting a Scala role in a few weeks yet I haven't written any Scala before (yes, my future employers know this), although I've written a lot of C# and Haskell. Anyway I was skimming through the Scala 3 book, and found this example:
enum Option[+T]:
case Some(x: T)
case None
Run Code Online (Sandbox Code Playgroud)
Which apparently dusugars into:
enum Option[+T]:
case Some(x: T) extends Option[T]
case None extends Option[Nothing]
Run Code Online (Sandbox Code Playgroud)
My two questions are:
这是一堂课,我正在打电话BlahMap:
class BlahMap t where
blahMap :: (m a -> n b) -> t m a -> t n b
Run Code Online (Sandbox Code Playgroud)
这是一个实例BlahMap:
instance BlahMap (ReaderT r) where
blahMap f = ReaderT . fmap f . runReaderT
Run Code Online (Sandbox Code Playgroud)
Haskell 生态系统中是否有现有的类可以执行此操作?或者,我可以只blahMap用现有类mtl或类似的东西编写一个具有适当约束的函数吗?或者我真的发明了一些新东西吗?