我正在尝试在 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
我正在尝试使用“更快的协程管道”一文中描述的抽象来构建一个流媒体库。我修改了代码,以便它正确处理管道退出(而不是在发生这种情况时抛出错误):
-- | 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) 假设我们有一个类,Foo这样的实例Foo f为我们提供了实现Functor f,Foldable f和所需的一切Traversable f。为了避免重叠实例,可以在 newtype 包装器之间Foo和Functor, 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) 我想创建一个程序,强制它的用户输入文本,但不允许他删除任何一个,在C中这样做的简单方法是什么?
我唯一得到的是(c = getchar()) != EOF && c != '\b'哪些不起作用.有任何想法吗?
我的问题似乎与这个密切相关 。
我的代码解析 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) 举一个简单的例子,假设我想要一个类型来表示井字游戏标记:
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 中是否有任何强制约束的机制(除了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) 我试图创建一个适用于[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 …
我正在尝试将 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\nRun 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) 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)