我正在尝试实现一个数据结构,如果我使用无穷大进行数字比较,那就简单了.请注意,这不是maxBound/minBound,因为值可以<= maxbound,但所有值都是<infinity.
没希望?
出于教育目的,我在Haskell玩树.我的Tree a
类型定义如下
data Tree a = EmptyTree | Node a (Tree a) (Tree a)
Run Code Online (Sandbox Code Playgroud)
和很多共享基本约束的函数Ord a
- 所以他们有类似的类型
treeInsert :: Ord a => a -> Tree a -> Tree a
treeMake :: Ord a => [a] -> Tree a
Run Code Online (Sandbox Code Playgroud)
等等.我也可以Tree a
这样定义
data Ord a => Tree a = EmptyTree | Node a (Tree a) (Tree a)
Run Code Online (Sandbox Code Playgroud)
但我不能简化我的功能,省略额外Ord a
的如下:
treeInsert :: a -> Tree a -> Tree a
treeMake :: [a] -> Tree a …
Run Code Online (Sandbox Code Playgroud) 我在Haskell中有这段代码拒绝编译:
data (Eq a, Num a, Show a) => Mat a = Mat {nexp :: Int, mat :: QT a}
deriving (Eq, Show)
data (Eq a , Show a ) => QT a = C a | Q (QT a ) (QT a ) (QT a ) (QT a )
deriving (Eq, Show)
cs:: (Num t) => Mat t -> [t]
cs(Mat nexp (Q a b c d)) =(css (nexp-1) a c)++(css (nexp-1) b d)
where
css 0 (C a) …
Run Code Online (Sandbox Code Playgroud) 在Data.FixedList的源代码中,我找到了以下定义:
data FixedList f =>
Cons f a = (:.) {
head :: a,
tail :: (f a)
} deriving (Eq, Ord)
Run Code Online (Sandbox Code Playgroud)
作为Haskell的新手,很难弄清楚这里发生了什么.我理解语法,如data TypeName = TypeName { a :: Int, b :: Int} deriving (Show)
或data TypeName = TypeA | TypeB
,但上面的代码是我的头脑.任何文档/或演练将非常感谢!
感谢这个问题的答案,我已经定义了这样一个类型:
data Chain = forall a. Integral a => Chain [[a]] [a] a a
Run Code Online (Sandbox Code Playgroud)
我需要为每个字段或参数编写一个getter函数,如果你愿意的话.这是我的第一次尝试:
getSimplices (Chain simplices _ _ _) = simplices
Run Code Online (Sandbox Code Playgroud)
但是当我尝试编译ghc时会出现以下错误:
Chain.hs:10:40: error:
• Couldn't match expected type ‘t’ with actual type ‘[[a]]’
because type variable ‘a’ would escape its scope
This (rigid, skolem) type variable is bound by
a pattern with constructor:
Chain :: forall a. Integral a => [[a]] -> [a] -> a -> a -> Chain,
in an equation for ‘getSimplices’
at …
Run Code Online (Sandbox Code Playgroud) 有很多关于GADTs
比 更好的问答DatatypeContexts
,因为 GADT 会自动在正确的位置提供约束。例如这里,这里,这里。但有时似乎我仍然需要一个明确的约束。这是怎么回事?改编自此答案的示例:
{-# LANGUAGE GADTs #-}
import Data.Maybe -- fromJust
data GADTBag a where
MkGADTBag :: Eq a => { unGADTBag :: [a] } -> GADTBag a
baz (MkGADTBag x) (Just y) = x == y
baz2 x y = unGADTBag x == fromJust y
-- unGADTBag :: GADTBag a -> [a] -- inferred, no Eq a
-- baz :: GADTBag a -> Maybe [a] -> …
Run Code Online (Sandbox Code Playgroud) 我有一个参数化类型,我想约束到一个数字类型,更具体地说是一个Fractional
,例如:
data Rating a = (Fractional a) => Score a | Unscored deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)
这样API的用户可以定义他们可能使用哪种非整数类型(Float
或Double
?),但我写的内部API代码仍然可以对数字类型执行算术运算.我不希望它是一个整数,因为我的"内部操作"的结果可能不是整数,我的理解是使用Fractional
会导致更准确的结果.
编译上面(至少在GHCI中)给出了以下错误:
Data constructor `Score' has existential type variables, a context, or a specialised result type
Score :: forall a. Fractional a => a -> Rating a
(Use ExistentialQuantification or GADTs to allow this)
In the definition of data constructor `Score'
In the data declaration for `Rating'
Run Code Online (Sandbox Code Playgroud)
这告诉我,我正在做一些我可能不想继续尝试的事情; 即我的设计是垃圾.
我想我试图在这个API中说出以下内容:"当你使用Rating类型时,它的参数必须是一个子类,Fractional
所以我可以对它执行准确的算术".我怎么能实现这个目标?还是我离开了标记和/或过度工程?