小编cro*_*eea的帖子

Haskell的最小完整定义注释

我为自己的数据类型定义了一个NumericPrelude Ring实例,但未能定义onefromInteger.当我编译程序时,我没有得到警告,因为Ring该类具有默认的相互递归实现onefromInteger.结果:堆栈溢出很难找到.(实际上,当使用-XRebindableSyntax时,fromIntegeron数字常量不需要是显式的,因此很难弄清楚fromInteger堆栈溢出的罪魁祸首.)

有没有办法让开发人员注释类以指示最小的完整定义?如果GHC可以对不符合此定义的实例发出警告,同时允许一组完整的默认实现,那将非常有用.如果没有,这里接受的做法是什么?开发人员是否应该保留(a?)最小的方法集而没有默认值,以便抛出适当的警告,或者我们依赖用户进行RTFM?

haskell annotations ghc

12
推荐指数
1
解决办法
1342
查看次数

静态链接C++库和Haskell库

设置:我有一个Haskell库HLib,可以调用C/C++后端CLib来提高效率.后端很小,专门用于HLib.的接口CLib被通过暴露HLib; HLib测试,HLib基准测试和第三方库依赖于HLib不会直接进行FFI调用CLib.从测试/基准/第三方lib的角度来看,HLib应该是纯粹的Haskell.这意味着在,例如小集团文件部分,HLib测试,应该有任何引用-lCLib,libCLib等等,只有build-dependsHLib,并且可执行文件不应该需要寻找一个动态CLib库.我需要能够构建和运行HLib第三方库中的所有可执行文件,以及运行cabal repl开发.

最初,CLib写于纯C.卡瓦尔具有用于这种情况下的支持,并且我可以集成CLibHLib在精确地,通过使用上面描述的方式include-dirs,c-sourcesincludes在小集团文件字段.

CLib已经发展成为一个C++库,我无法弄清楚如何让cabal轻松集成.相反,我使用自定义构建和Setup.hs的makefile,就像这样.你可以在这里看到这个方法的一个小例子1,2.

在那个例子中,我无法运行cabal repl,HLib因为"加载档案不受支持".这实际上意味着我需要一个动态C++库,它很容易创建(在CLibmakefile中有一个注释行来完成它).但是,如果我确实创建了动态C++库,那么HLib由于"没有这样的文件或目录libclib.so" ,测试会在运行时失败.这很糟糕(除了崩溃),因为测试可执行文件链接到动态库,这不是我想要的.

具体来说,测试HLibSimpleLib应该通过,我应该能够cabal repl在 …

haskell ghc cabal

12
推荐指数
1
解决办法
1370
查看次数

Haskell:为什么没有类型不匹配(为什么编译)?

我太困了以至于我编写了以下代码(修改后只显示了混乱):

fac s = take 10 [s, s `mod` 1 ..]

maxFactor x = if (s == [])
              then x
              else head    <-- this should be 'head x' instead of just 'head'
  where s = fac x
Run Code Online (Sandbox Code Playgroud)

但是,这个加载到ghci(和编译)就好了.当我执行时maxFactor 1,它抱怨(当然):

<interactive>:0:1:
    No instance for (Integral ([a0] -> a0))
      arising from a use of `maxFactor'
    Possible fix:
      add an instance declaration for (Integral ([a0] -> a0))
    In the expression: maxFactor 1
    In an equation for `it': it = maxFactor 1 …
Run Code Online (Sandbox Code Playgroud)

haskell types typeclass ghc ghci

11
推荐指数
2
解决办法
616
查看次数

矢量化模运算

我正在尝试编写一些合理快速的组件向量加法代码.我正在使用(签名,我相信)64位整数.

功能是

void addRq (int64_t* a, const int64_t* b, const int32_t dim, const int64_t q) {
    for(int i = 0; i < dim; i++) {
        a[i] = (a[i]+b[i])%q; // LINE1
    }
}
Run Code Online (Sandbox Code Playgroud)

我在icc -std=gnu99 -O3IvyBridge(SSE4.2和AVX,但不是AVX2)上编译(icc以便我以后可以使用SVML).

我的基线是%q从LINE1中删除.100(迭代)函数调用dim=11221184需要1.6秒.ICC自动矢量化SSE代码; 大.

我真的想做模块化的补充.使用%q,ICC不会自动向量化代码,它在11.8秒(!)内运行.即使忽略了之前尝试的自动矢量化,这似乎仍然过分.

由于我没有AVX2,SSE的矢量化需要SVML,这也许就是为什么ICC没有自动矢量化的原因.无论如何,这是我尝试对内循环进行矢量化:

__m128i qs = _mm_set1_epi64x(q);
for(int i = 0; i < dim; i+=2) {
    __m128i xs = _mm_load_si128((const __m128i*)(a+i));
    __m128i ys = _mm_load_si128((const __m128i*)(b+i));
    __m128i zs = _mm_add_epi64(xs,ys);
    zs = _mm_rem_epi64(zs,qs);
    _mm_store_si128((__m128i*)(a+i),zs);
}
Run Code Online (Sandbox Code Playgroud)

主循环的汇编是: …

c assembly sse x86-64 intrinsics

11
推荐指数
1
解决办法
1401
查看次数

分析部分评估的程序

为了分析部分评估的程序,我有兴趣了解终止GHC程序的最佳方法.这对于分析需要很长时间才能运行的程序非常有用,可能只需要永久运行.

使用GHC 7.4.2,我能够通过启用分析(-prof -auto-all)和运行我的程序来分析非终止程序+RTS -p.这会生成增量分析数据.该程序可能会被杀死^c,而.prof文件将包含数据.在GHC 7.6及更高版本中,似乎如果程序可以用单个^ c终止,则将分析信息写入输出.然而(特别是对于更新版本的GHC?)单个^ c不会杀死程序,至少在我不耐烦之前并再次点击^ c.通常两个^ c将终止程序,但之后没有将分析数据写入输出.

具体来说,请考虑尝试分析StupidFib.hs的问题:

fib n = fib (n - 1) + fib (n - 2)
main = print $ fib 100
Run Code Online (Sandbox Code Playgroud)

使用-prof进行编译并使用+ RTS -p运行,我可以在执行的第一个大约10秒内使用单个 ^ c 终止此程序,但之后只有两个^ c将执行该作业.看看我的资源,这个变化似乎与使用我所有物理内存并转移到交换空间的程序一致,但这可能是巧合.

为什么^ c有时会工作,而不是同一个程序的其他时间?当程序没有自行终止时,确保分析数据打印的最简单方法是什么?

profiling haskell ghc

11
推荐指数
1
解决办法
371
查看次数

GHC在多个范围内选择哪个词典?

请考虑以下示例:

import Data.Constraint

class Bar a where
  bar :: a -> a

foo :: (Bar a) => Dict (Bar a) -> a -> a
foo Dict = bar
Run Code Online (Sandbox Code Playgroud)

在选择Bar实例时,GHC有两种选择foo:字典可以使用Bar a约束中的字典foo,或者它可以使用运行时Dict来获取字典.有关字典对应不同实例的示例,请参阅此问题.

GHC使用哪种词典,为什么它是"正确的"选择?

haskell ghc

11
推荐指数
3
解决办法
323
查看次数

记忆乘法

我的应用程序在使用FFT进行(昂贵)转换后将向量相乘.结果,当我写作

f :: (Num a) => a -> [a] -> [a]
f c xs = map (c*) xs
Run Code Online (Sandbox Code Playgroud)

我只想计算c一次FFT ,而不是计算每个元素的FFT xs.确实没有必要c为整个程序存储FFT ,只需在本地范围内.

我试图将我的Num实例定义为:

data Foo = Scalar c
         | Vec Bool v -- the bool indicates which domain v is in

instance Num Foo where
    (*) (Scalar c) = \x -> case x of
                         Scalar d -> Scalar (c*d)
                         Vec b v-> Vec b $ map (c*) v
    (*) v1 = let Vec …
Run Code Online (Sandbox Code Playgroud)

haskell memoization currying

10
推荐指数
1
解决办法
418
查看次数

解决外部库中的重叠实例

我正在尝试在也从加速库导入的模块show中输入类型Tagged s b(Data.Tagged).不幸的是,加速库定义了show实例

instance Kit acc => Show (acc aenv a) where
Run Code Online (Sandbox Code Playgroud)

在Data.Array.Accelerate.Pretty.hs中.稍微阅读一下,我无法避免导入此实例,这显然与Data.Tagged Show实例重叠.事实上,通用加速实例阻止我打印任何类型的东西*->*->*.

这是一个演示问题的简单示例:

{-# LANGUAGE FlexibleContexts, OverlappingInstances, IncoherentInstances #-}

import Data.Array.Accelerate
import Data.Tagged

main :: (Show (Tagged Int Int)) => IO ()
main = let x = Tagged 3
   in print (x::Tagged Int Int)
Run Code Online (Sandbox Code Playgroud)

错误:

    Overlapping instances for Show (Tagged * Int Int)
      arising from a use of `print'
    Matching instances:
      instance Show b => Show (Tagged …
Run Code Online (Sandbox Code Playgroud)

haskell namespaces multiple-instances overlapping-instances

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

在类型系列中显示自定义类型错误

GHC 8.0具有用户定义类型错误的功能.我正在尝试,但我不能完全做到我想要的:

{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
             TypeFamilies, TypeOperators, UndecidableInstances #-}

import Data.Proxy
import GHC.TypeLits

data DoubleD
data IntD

type family CTypeOf x where
  CTypeOf (a,b) = EqCType (CTypeOf a) (CTypeOf b)
  CTypeOf Double = DoubleD
  CTypeOf Int = IntD

  CTypeOf a = TypeError (Text "Unsupported type: " :<>: ShowType a)

type family EqCType a b where
  EqCType a a = a
  EqCType a b = TypeError (Text "Pair error")

class (repr ~ CTypeOf r) => Dispatch' …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

10
推荐指数
0
解决办法
310
查看次数

生成具有恒定堆栈空间的随机向量

我正在使用Don Stewart 的软件包System.Random.Mersenne.Pure64Control.Monad.Mersenne.Random,它们通常非常快,并且应该有助于避免常见错误,例如使用非严格状态monad.

尽管如此,我设法编写了一些代码,这些代码会导致中等大小的向量堆栈溢出.

import qualified Data.Vector.Unboxed as U
import Data.Int
import System.Random.Mersenne.Pure64
import Control.Monad.Mersenne.Random

main = do
    let dim = 1000000
        y = evalRandom (U.replicateM dim getInt64) (pureMT 13) :: U.Vector Int64
    putStr $ (show $ U.head y)
Run Code Online (Sandbox Code Playgroud)

我猜这一定是由于Vector的replicateM实现中的懒惰,虽然它很难看到,因为它是使用实现的streams.

我如何编写使用常量堆栈空间来采样大向量的代码?

stack-overflow monads haskell lazy-evaluation

8
推荐指数
1
解决办法
200
查看次数