小编Ice*_*ack的帖子

如何在 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
查看次数

忽略stdin的退格键

我想创建一个程序,强制它的用户输入文本,但不允许他删除任何一个,在C中这样做的简单方法是什么?

我唯一得到的是(c = getchar()) != EOF && c != '\b'哪些不起作用.有任何想法吗?

c stdin backspace

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

避免 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] 模拟的语法,但类型 (* -> *)

我试图创建一个适用于[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
查看次数

将 GADT 与 DataKinds 结合使用以实现函数中的类型级数据构造函数约束

我正在尝试将 GADT 与 DataKinds 结合使用,如下所示

\n
{-# LANGUAGE KindSignatures, DataKinds, GADTs #-}\nmodule NewGadt where\n\ndata ExprType = Var | Nest\n\ndata Expr (a :: ExprType) where\n  ExprVar :: String -> Expr Var\n  ExprNest :: Expr a -> Expr Nest\n\ndata BaseExpr\n  = BaseExprVar String\n  | BaseExprNest BaseExpr\n\ntranslate :: BaseExpr -> Expr a\ntranslate (BaseExprVar id) = ExprVar id\ntranslate (BaseExprNest expr) = ExprNest $ translate expr\n
Run Code Online (Sandbox Code Playgroud)\n

编译错误:

\n
/home/elijah/code/monty/src/NewGadt.hs:15:32: error:\n    \xe2\x80\xa2 Couldn\'t match type \xe2\x80\x98a\xe2\x80\x99 with \xe2\x80\x98\'Var\xe2\x80\x99\n      \xe2\x80\x98a\xe2\x80\x99 is a rigid type variable bound …
Run Code Online (Sandbox Code Playgroud)

haskell existential-type gadt data-kinds

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

在 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
查看次数