我们可以为类型参数编写单个,全面的实例*:
class MyClass d where
f :: d -> Int
instance MyClass (Maybe d) where
f _ = 3
test1 :: Maybe d -> Int
test1 x = f x
Run Code Online (Sandbox Code Playgroud)
编译得很好,并注意我们在test1上不需要(MyClass(Maybe d))约束,因为编译器会找到任何匹配的实例Maybe d.
我们甚至可以为类型构造函数的类参数编写一个包罗万象的实例:
class MyClass2 (a :: * -> *) where
g :: Tagged (a Int) Int
instance MyClass2 a where
g = Tagged 3
test2 :: Int
test2 = untag (g :: Tagged (Maybe Int) Int)
Run Code Online (Sandbox Code Playgroud)
这也编译得很好,而test2不需要(MyClass2 Maybe)约束,因为编译器找到了匹配的实例.
考虑以下玩具代码来计算(提升的)类型列表的长度:
{-# LANGUAGE TypeOperators,
DataKinds,
KindSignatures, …Run Code Online (Sandbox Code Playgroud) SPECIALIZE在试图找到解决这个问题的方法的时候,我正在搞乱这个pragma .
我想出了这个例子:
{-# LANGUAGE FlexibleContexts, GeneralizedNewtypeDeriving #-}
import Data.Vector
import qualified Data.Vector.Generic as V
class Foo a
newtype Phantom m = T Int deriving (Show)
instance (Foo m) => Num (Phantom m)
f :: (Num r, V.Vector v r) => v r -> v r -> v r
{-# SPECIALIZE f :: (Foo m) => Vector (Phantom m) -> Vector (Phantom m) -> Vector (Phantom m) #-}
f x y = V.zipWith (+) x y
main …Run Code Online (Sandbox Code Playgroud) 我一直在尝试制作功能图.我正在制作的图形没有循环,所以它有点像树,其中一些节点可以有多个父节点.
问题在于更新时.树的常用方法是遍历到要更新的节点,创建新节点的每一步都被更改为指向新的子节点,直到达到要修改的实际节点然后实际的数据是改变.
当某些节点有多个父节点断开时采用这种方法,因为最终基本上"拆分"节点.在两个父节点之间共享的节点变为两个节点,每个节点具有父节点,一个节点(您遍历到达节点的路径)具有新值,另一个父节点保持具有旧值的子节点.
所以我试着在每个节点内存储父节点,即节点知道他们的父母是谁.
这有效,但有一个问题.如果我更新节点,我必须更新其父节点.但是对于每个父母,我不仅要更新他们的父母,还要更新他们的孩子,因为他们的孩子存储他们的父节点,并且父节点现在已经改变了.
因此,要更新一个节点值,我必须更新图中的每个节点.
我的另一个想法是不是在每个节点中存储父节点,只是将"路径"存储到每个节点中的父节点.这样我就不必更新父节点的子节点,因为父节点的"路径"没有改变(即使节点本身有).
但也许有更好的方法来构建功能图?有任何想法吗?我不介意它是否不处理带循环的图形.我在Haskell编码,但非编程语言描述也可以.
这是一些简单的代码,需要-XRebindableSyntax.
{-# LANGUAGE RebindableSyntax, NoImplicitPrelude #-}
import NumericPrelude
import qualified Algebra.Additive (C)
import qualified Algebra.Ring (C)
newtype Foo = Foo Int deriving (Show)
instance Algebra.Additive.C Foo where
(Foo x) + (Foo y) = Foo (x+y)
instance Algebra.Ring.C Foo where
fromInteger = Foo . fromInteger
f :: Foo -> Foo -> Foo
f x y = x + y
g = f 3 5
Run Code Online (Sandbox Code Playgroud)
这是我的 GHCi 成绩单:
> ghci Foo.hs
GHCi, version 7.8.2
...
*Main> g
Foo 8
*Main> …Run Code Online (Sandbox Code Playgroud) 这编译代码是一个最小化的例子的代码从一个答案,这个问题与句法2.0.我也在Data.Type.Equality中使用sameModType派生的定义sameNat.
我一直在使用这个解决方案没有问题,但我想使模数q是类型多态的,具体的目标是Proxy (nat :: Nat)做到nat :: Nat(虽然仍然能够使用模数*).
{-# LANGUAGE GADTs,
MultiParamTypeClasses,
FunctionalDependencies,
FlexibleContexts,
FlexibleInstances,
TypeOperators,
ScopedTypeVariables,
DataKinds,
KindSignatures #-}
import Data.Tagged
import Data.Proxy
import Data.Type.Equality
import Data.Constraint
import Unsafe.Coerce
import GHC.TypeLits
newtype Zq q i = Zq i
data ZqType q
where
ZqType :: (Modulus q Int) => Proxy q -> ZqType (Zq q Int)
class (Integral i) => Modulus a i | a …Run Code Online (Sandbox Code Playgroud) 这是代码:
{-# LANGUAGE RankNTypes, FlexibleContexts, ScopedTypeVariables #-}
module Foo where
import Data.Vector.Generic.Mutable as M
import Data.Vector.Generic as V
import Control.Monad.ST
import Control.Monad.Primitive
import Control.Monad
data DimFun v s r =
DimFun {dim::Int, func :: v (PrimState s) r -> s ()}
runFun :: (Vector v r) =>
(forall s . (PrimMonad s) => DimFun (Mutable v) s r) -> v r -> v r
runFun t x = runST $ do
y <- thaw x
evalFun t y
unsafeFreeze y …Run Code Online (Sandbox Code Playgroud) 我试图将任意右嵌套对(即)的Haskell 向量表示为Vector (Int64, (Int64, (...)))C(即int64_t**)中的2-d数组,首先索引为向量组件,然后是元组组件.
这是我的C函数:
void test(int64_t** y, int32_t vecSize int16_t tupSize, int64_t* tup)
{
printf("Tup vals: ");
for(int i = 0; i < tupSize; i++) {
printf("%" PRId64 ",",tup[i]);
}
printf("\n");
printf("vec\n");
for(int i = 0; i < vecSize; i++) {
printf("%d: (", i);
for(int j = 0; j < tupSize; j++) {
printf("%" PRId64 ",", y[i][j]);
}
printf(")\n");
}
}
Run Code Online (Sandbox Code Playgroud)
在Haskell方面,我有:
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Int
import Data.Vector.Storable (Vector, singleton, unsafeWith) …Run Code Online (Sandbox Code Playgroud) 我发现使用GHC的FFI有两种调用约定:ccall和capi.这些文档没有太多关于这两个公约的信息.它们之间有什么区别,我什么时候应该使用它们?一个比另一个快吗?
使用-XDuplicateRecordFields,允许以下内容:
{-# LANGUAGE DuplicateRecordFields #-}
module Baz(Foo(..), Bar(..)) where
data Foo = Foo {qux :: Int}
data Bar = Bar {qux :: String}
Run Code Online (Sandbox Code Playgroud)
但是,Foo在模块中定义Foo并在模块Bar中定义时出现编译错误Bar:
{-# LANGUAGE DuplicateRecordFields #-}
module Baz(Foo(..), Bar(..)) where
import Foo (Foo(..))
import Bar (Bar(..))
Run Code Online (Sandbox Code Playgroud)
Conflicting exports for ‘qux’
我认为我正在尝试做的相当于第一个示例;最初定义数据类型的位置无关紧要。GHC 8 支持这种功能吗?
我最近遇到了使用GADT类型多态性的问题.答案是为我的数据类型提供"完整的用户指定类型"(CUSK).我已经阅读了相关文档,但是当我尝试将它应用于类时,我仍然得到基本相同的错误.
具体而言,有一次我给一个单鳍鳕,下面做编译:
{-# LANGUAGE DataKinds, PolyKinds, GADTs #-}
data Foo (x :: k) where
C :: Foo x -> Foo '(x,x)
Run Code Online (Sandbox Code Playgroud)
但是当我将该定义移到一个类时:
{-# LANGUAGE DataKinds, PolyKinds #-}
class Foo (f :: k -> *) where
foo :: (f :: k1 -> *) (x :: k1) -> (f :: (k1,k1) -> *) ('(x,x) :: (k1,k1))
Run Code Online (Sandbox Code Playgroud)
我收到错误:
• Expected kind ‘(k1, k1) -> *’, but ‘f’ has kind ‘k -> *’
• In the …Run Code Online (Sandbox Code Playgroud)