标签: derivingvia

量化约束与(封闭)类型系列

我正在尝试使用这篇博文的方法来处理更高级的数据,而无需Identity为琐碎的情况使用悬空函子以及量化约束推导:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE QuantifiedConstraints, StandaloneDeriving, UndecidableInstances #-}
module HKD2 where

import Control.Monad.Identity

type family HKD f a where
    HKD Identity a = a
    HKD f        a = f a

data Result f = MkResult
    { foo :: HKD f Int
    , bar :: HKD f Bool
    }

deriving instance (forall a. Show a => Show (HKD f a)) => Show (Result f)
Run Code Online (Sandbox Code Playgroud)

这导致了令人气愤的自相矛盾的错误信息:

无法Show (HKD f a) 从上下文推断:forall a. Show …

haskell type-families deriving quantified-constraints derivingvia

9
推荐指数
2
解决办法
262
查看次数

新类型的 Haskell Monoid 实例问题

我正在尝试定义一个实例:

newtype Join a = Join { getJoin :: a -> Bool }
   deriving Generic

instance Monoid (Join a) where
   f <> g = ???
   mempty = ???
Run Code Online (Sandbox Code Playgroud)

目标是如果列表中的所有函数都为真,则函数 foldMap Join 应该返回 True,如果所有函数都不为真,则返回 false。

我了解 foldMap 以及 Monoid 的 Sum 和 Product 实例,但对于编写 Monoid 的 newtype 实例我还是很陌生的。任何在正确方向上的帮助将不胜感激。谢谢你。

haskell monoids deriving newtype derivingvia

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

如何在 Haskell 中将自定义类型转换为整数?

我正在尝试在 Haskell 中使用我自己的数据类型来表示质数,但我目前遇到了一些问题。

newtype Prime = Prime Integer deriving (Eq, Ord, Typeable, Show)
Run Code Online (Sandbox Code Playgroud)

只要我对质数(例如下面的“phi”函数)进行任何数字运算,我就想将结果作为整数处理,但我不知道该怎么做。

phi :: Prime -> Prime -> Integer
phi p q = (p-1)*(q-1)
Run Code Online (Sandbox Code Playgroud)

phi 应该返回一个整数,因为它不再是质数了。我得到的只是预期的错误消息:

    • Couldn't match expected type ‘Integer’ with actual type ‘Prime’
    • In the expression: (p - 1) * (q - 1)
      In an equation for ‘genPhi’: genPhi p q = (p - 1) * (q - 1)
Run Code Online (Sandbox Code Playgroud)

那么如何将我的自定义类型转换为整数?我对 Haskell 没有太多经验。

haskell functional-programming algebraic-data-types custom-data-type derivingvia

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

如何实现将两个消费者合二为一的 fork 功能

我正在尝试使用“更快的协程管道”一文中描述的抽象来构建一个流媒体库。我修改了代码,以便它正确处理管道退出(而不是在发生这种情况时抛出错误):

-- | r: return type of the continuation, i: input stream type, o: output stream type,
--   m: underlying monad, a: return type
newtype ContPipe r i o m a = MakePipe {runPipe :: (a -> Result r m i o) -> Result r m i o}
  deriving
    ( Functor,
      Applicative,
      Monad
    )
    via (Cont (Result r m i o))

type Result r m i o = InCont r m i -> OutCont r m o -> m r …
Run Code Online (Sandbox Code Playgroud)

continuations haskell stream deriving derivingvia

6
推荐指数
0
解决办法
97
查看次数

是否可以通过另一个类型构造函数派生一个 Traversable 实例?

假设我们有一个类,Foo这样的实例Foo f为我们提供了实现Functor f,Foldable f和所需的一切Traversable f。为了避免重叠实例,可以在 newtype 包装器之间FooFunctor, Foldable, Traversable下见证这种关系:

type Foo :: (Type -> Type) -> Constraint
class Foo f
  where
  {- ... -}

type FoonessOf :: (Type -> Type) -> Type -> Type
newtype FoonessOf f a = FoonessOf (f a)

instance Foo f => Functor (FoonessOf f)
  where
  fmap = _

instance Foo f => Foldable (FoonessOf f)
  where
  foldMap = _

instance Foo …
Run Code Online (Sandbox Code Playgroud)

haskell deriving derivingvia

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

避免 Haskell 中重复的实例声明

我的问题似乎与这个密切相关 。

我的代码解析 yaml 文件,重新排列对象并写入一个新的 yaml 文件。它工作得很好,但有一个特别难看的部分。

我必须将我的数据结构声明为 的实例,FromJson如下ToJson所示:

instance FromJSON Users where
  parseJSON = genericParseJSON (defaultOptions { fieldLabelModifier = body_noprefix })
instance ToJSON Users where
  toJSON = genericToJSON (defaultOptions { fieldLabelModifier = body_noprefix })
Run Code Online (Sandbox Code Playgroud)

问题是我必须对 8 个左右的其他情况重复此操作:

instance FromJSON Role where
  parseJSON = genericParseJSON (defaultOptions { fieldLabelModifier = body_noprefix })
instance ToJSON Role where
  toJSON = genericToJSON (defaultOptions { fieldLabelModifier = body_noprefix })

...
...
Run Code Online (Sandbox Code Playgroud)

我不知道如何避免这种重复。是否有某种方法可以仅声明两个函数一次(例如在新类中)并让所有这些数据类型从中派生?

解决方案(另请参阅 dfeuer 接受的答案):

我个人喜欢这个解决方案。你需要添加

{-# language DerivingVia …
Run Code Online (Sandbox Code Playgroud)

haskell dry instance deriving derivingvia

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

是否可以在自定义类型和标准库类型之间建立 Coercible 实例?

举一个简单的例子,假设我想要一个类型来表示井字游戏标记:

data Mark = Nought | Cross
Run Code Online (Sandbox Code Playgroud)

这与 Bool

Prelude> :info Bool
data Bool = False | True    -- Defined in ‘GHC.Types’
Run Code Online (Sandbox Code Playgroud)

但是Coercible Bool Mark它们之间没有,即使我导入GHC.Types(我最初认为 GHC 可能需要Bool定义可见的位置),获得此实例的唯一方法似乎是通过newtype.

也许我可以这样来定义newtype Mark = Mark Bool和界定Nought,并Cross具有双向模式,我希望有东西比这更简单。

haskell coerce deriving derivingvia

5
推荐指数
3
解决办法
153
查看次数

如何强制约束?

在 Haskell 中是否有任何强制约束的机制(除了unsafeCoerce我希望有效)?

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
module CatAdjonctionsSOQuestion where

import Data.Proxy
import Data.Tagged
import Unsafe.Coerce

newtype K a ph = K {unK :: a} -- I would want c a => c ((K a) i) for any c :: Constraints

-- I could do any …
Run Code Online (Sandbox Code Playgroud)

haskell deriving derivingvia

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

是否有创建 [Maybe a] 模拟的语法,但类型 (* -&gt; *)

我试图创建一个适用于[Maybe a]. 但是, Maybe a 有 kind *,而 fmap 需要 kind * -> *。这导致了以下不幸的解决方案:

newtype Unfortunate a = Unfortunate ([Maybe a]) deriving Show

instance Functor Unfortunate
    where fmap f (Unfortunate a) = Unfortunate $ (fmap (fmap f)) a


-- |
-- >>> l = Unfortunate [Just 10, Just 1, Nothing, Just 15]
-- >>> fmap (*5) l
-- Unfortunate [Just 50,Just 5,Nothing,Just 75]
Run Code Online (Sandbox Code Playgroud)

不幸的是必须创建一个newtype。我希望可以创建一个适用于 的实例,适用[Maybe a]于任何a. 即,可以称为fmap f [Just …

syntax haskell typeclass deriving derivingvia

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

在 Scala 3 中派生不透明类型的类型类实例

Scala 3 中有没有办法将derives关键字与不透明类型别名结合使用?最好有一种无样板的方法,通过自动依赖基础类型(如果有)的相同类型类的实例来为给定的不透明类型别名提供类型类实例。

如果能够表达类似的东西就好了

opaque type Id = Int 
object Id:
  given Show[Id] = Show.intShow
Run Code Online (Sandbox Code Playgroud)

对于某些假设的类型类Show,如

opaque type Id = Int derives Show
Run Code Online (Sandbox Code Playgroud)

scala typeclass deriving scala-3 derivingvia

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

这个“派生新类型”语法是什么?

从我读过的一篇博客文章

-- | Newtype for disabling logging
newtype NoLoggingT m a
  = NoLoggingT { runNoLoggingT :: m a }
  deriving newtype (Functor, Applicative, Monad)
  deriving (MonadTrans) via IdentityT

instance Monad m => MonadLog (NoLoggingT m) where logLn _ _ = pure ()
Run Code Online (Sandbox Code Playgroud)

那是什么deriving newtype语法?它是哪个扩展名,它有什么作用?请在 anwser 中提供指向其文档的链接。

haskell deriving derivingvia

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

为包含不能有 Eq 或 Show 的字段的 ADT 派生 Eq 和 Show

我希望能够为包含多个字段的 ADT派生Eq和派生Show。其中之一是功能字段。这样做时Show,我希望它显示一些虚假的东西,例如"<function>"; 这样做时Eq,我希望它忽略该字段。我怎样才能最好地做到这一点,而无需为Showand手写一个完整的实例Eq

我不想将函数字段包装在 a 中并为此newtype编写我自己的字段- 那样使用太麻烦了。EqShow

haskell deriving derivingvia

3
推荐指数
2
解决办法
121
查看次数