小编Mik*_*cki的帖子

将类型级别自然数转换为常规数

我试图通过一个实现点积的简单例子来获得类型级自然数的悬念.我代表这样的点积:

data DotP (n::Nat) = DotP [Int]
    deriving Show
Run Code Online (Sandbox Code Playgroud)

现在,我可以mappend为点积的每个单独大小创建一个monoid实例(实际的点积),如下所示:

instance Monoid (DotP 0) where
    mempty                      = DotP $ replicate 0 0
    mappend (DotP xs) (DotP ys) = DotP $ zipWith (*) xs ys

instance Monoid (DotP 1) where
    mempty                      = DotP $ replicate 1 0
    mappend (DotP xs) (DotP ys) = DotP $ zipWith (*) xs ys

instance Monoid (DotP 2) where
    mempty                      = DotP $ replicate 2 0
    mappend (DotP xs) (DotP ys) = DotP $ …
Run Code Online (Sandbox Code Playgroud)

haskell types

7
推荐指数
1
解决办法
548
查看次数

为什么Data.Binary的encodeFile不会表现得很懒惰?

在GHCI中,我运行这个简单的测试:

encodeFile "test" [0..10000000]
Run Code Online (Sandbox Code Playgroud)

该线路运行速度非常快(<10秒),但我的内存使用量在完成之前会达到~500MB.不应该编码文件是懒惰的,因为它使用ByteString.Lazy?


编辑:罗曼的答案很棒!我还想指出另一个问题的答案,这解释了为什么Data.Binary对列表进行严格编码并提供稍微优雅的解决方法.

haskell

6
推荐指数
1
解决办法
202
查看次数

使用Data.Binary对列表进行延迟解码

我懒惰地使用这段代码编码列表(取自这个SO问题):

import Data.Binary

newtype Stream a = Stream { unstream :: [a] }

instance Binary a => Binary (Stream a) where

    put (Stream [])     = putWord8 0
    put (Stream (x:xs)) = putWord8 1 >> put x >> put (Stream xs)
Run Code Online (Sandbox Code Playgroud)

问题是解码实现不是懒惰的:

    get = do
        t <- getWord8
        case t of
            0 -> return (Stream [])
            1 -> do x         <- get
                    Stream xs <- get
                    return (Stream (x:xs))
Run Code Online (Sandbox Code Playgroud)

这看起来像我应该是懒惰的,但是如果我们运行这个测试代码:

head $ unstream (decode $ encode $ Stream [1..10000000::Integer] …
Run Code Online (Sandbox Code Playgroud)

haskell lazy-evaluation

6
推荐指数
1
解决办法
773
查看次数

快速检查非布尔测试

我正在使用QuickCheck来测试我的代码以进行一些数值计算.基本上我有一个确切的功能和几个近似的效率更高.

我目前正在实现我想要测试的属性:

prop_blah input = (abs $ (exact input)-(approx input)) < threshold
Run Code Online (Sandbox Code Playgroud)

但是,确切地知道每种近似算法的准确度并将它们相互比较真的很不错.一种简单的方法是获得不等式左侧的均值和标准差的报告.这有点可能吗?

haskell quickcheck

6
推荐指数
1
解决办法
442
查看次数

我们可以将不可变列表视为树的双重列表吗?

我可能会画一个单词列表,如:

this -> is -> a -> test
Run Code Online (Sandbox Code Playgroud)

然后通过分享,我可以绘制两个列表:

this -> is -> a -> test
                     ^
                     |
that -> was -> a -> hard
Run Code Online (Sandbox Code Playgroud)

现在,如果我反转箭头,我得到一棵树,以测试为根.这与图/类别理论中的二元性概念相同.因此,我可以将树木和列表视为双重概念.

这是正确/有用的吗?

tree haskell functional-programming list data-structures

6
推荐指数
1
解决办法
187
查看次数

你怎么称待服从某些约束的类型集合?

给定一个功能

f :: Vector a => a -> b
Run Code Online (Sandbox Code Playgroud)

我们会调用a一个类型(或类型变量)和Vector一个约束.但是我们称之为满足所有类型的集合Vector a => a呢?我一直在非正式地称它为"矢量空间集",我将任何成员类型称为"向量空间".我应该使用更准确的类型理论名称吗?特别是,"set"和"space"这两个词是否正确使用?

haskell types terminology definition

6
推荐指数
0
解决办法
104
查看次数

如何使用bash测试cabal

对于我的项目,我已经将一些单元测试写成了bash脚本.确实没有合理的方法在Haskell中编写测试.

我想在输入时运行这些脚本cabal test.我该如何做到这一点?

haskell cabal

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

成本敏感的折叠

让我用一个例子解释一下成本敏感折叠的含义:用任意精度计算pi.我们可以使用Leibniz公式(效率不高,但又好又简单)和懒惰的列表如下:

pi = foldr1 (+) [(fromIntegral $ 4*(-1)^i)/(fromIntegral $ 2*i+1) | i<-[0..]]
Run Code Online (Sandbox Code Playgroud)

现在,显然这个计算永远不会完成,因为我们必须计算无限列表中的每个值.但实际上,我不需要pi的确切值,我只需要它到指定的小数位数.我可以像这样定义pi':

pi' n = foldr1 (+) [(fromIntegral $ 4*(-1)^i)/(fromIntegral $ 2*i+1) | i<-[0..n]]
Run Code Online (Sandbox Code Playgroud)

但是,根本不清楚我需要传递什么值以获得我想要的精度.我需要的是某种对成本敏感的折叠,只要达到所需的精度就会停止折叠.这样的折叠存在吗?

(注意,在这种情况下,很容易看出我们是否已达到所需的精度.因为Leibniz公式使用了一个与每个术语交替出现符号的序列,所以误差总是小于下一个术语的绝对值.序列.)

编辑:拥有对成本敏感的折叠也很酷,这也可以考虑计算时间/功耗.例如,我想要最准确的pi值,因为我有1小时的计算时间和10kW小时的花费.但我意识到这将不再具有严格的功能.

haskell functional-programming fold

4
推荐指数
2
解决办法
211
查看次数

使用Type Nats创建类型级别列表(在类型级别添加数字时出现问题)

只是为了好玩,我想创建一个类型级列表,知道它有多长.像这样的东西:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}

import GHC.TypeLits

data family TypeList a (n::Nat)

data instance TypeList a (0) = EmptyList
data instance TypeList a (1) = TL1 a (TypeList a (0))
data instance TypeList a (2) = TL2 a (TypeList a (1))
data instance TypeList a (3) = TL3 a (TypeList a (2))
Run Code Online (Sandbox Code Playgroud)

但是,我当然希望将其概括为:

data instance TypeList a (n)   = TL3 a (TypeList a (n-1))
Run Code Online (Sandbox Code Playgroud)

但这会产生错误:

    TypeList.hs:15:53: parse error on input `-'
    Failed, …
Run Code Online (Sandbox Code Playgroud)

haskell types

4
推荐指数
1
解决办法
687
查看次数

travis-ci何时支持ghc 7.10?

我想在我的Haskell项目中使用travis-ci,但它们需要最新版本的GHC.

haskell travis-ci

4
推荐指数
1
解决办法
180
查看次数

部分未装箱的载体

我有一个表单的数据类型:

data T = { a :: Int, b :: ComplexOtherDataType }
Run Code Online (Sandbox Code Playgroud)

我显然可以将这些放入Data.Vector模块的常规向量中.但是当我访问a组件时,我想要非常,非常好的性能,因此额外的间接是不可取的.我想做的是做T一个实例Data.Vector.Unboxed.Unbox,但仍然b是懒惰的.

vector-th-unbox提供了用于制备的实例的漂亮的模板哈斯克尔接口Unbox,但它不会在我的情况下工作.它要求,为了使T实例Unbox,都a b也必须实例.但我不想拆箱b.我希望它是盒装/懒惰的.

我的直觉说,克服这个障碍的最简单方法是提供一种类型

newtype LazyUnbox a = LazyUnbox a
Run Code Online (Sandbox Code Playgroud)

然后,我需要提供一个Unbox实例LazyUnbox,基本上只是将指针存储在未装箱的矢量中.我怎样才能做到这一点?还是完全有更好的方法?

haskell vector lazy-evaluation

3
推荐指数
1
解决办法
288
查看次数

是否有任何理由在 postgres 表中而不是在索引中包含一个 `tsvector` 列?

我有一个包含大约 1 亿行的表格和一个我想搜索的文本字段。我想出了两种方法来做到这一点,我想知道每种方法的性能影响。

方法 1: 这是我在网上看到的每篇博文都推荐的方法(例如12 .)。这个想法是用一ts_vector列扩充表并索引新列。
一个简单的例子是:

CREATE TABLE articles (
    id_articles BIGSERIAL PRIMARY KEY,
    text TEXT,
    text_tsv TSVECTOR
);
CREATE INDEX articles_index ON articles USING gin(text_tsv);
Run Code Online (Sandbox Code Playgroud)

然后使用触发器来确保texttext_tsv列保持最新。
然而,这对我来说似乎很浪费,因为现在TSVECTOR信息必须同时存储在表和索引中,并且数据库变得更加复杂。所以我想出了第二种方法。

方法二: 我的想法是去掉多余的列,改索引to_tsvector直接包含函数,像这样:

CREATE TABLE articles (
    id_articles BIGSERIAL PRIMARY KEY,
    text TEXT
);
CREATE INDEX articles_index ON articles USING gin(to_tsvector(text));
Run Code Online (Sandbox Code Playgroud)

问题:与方法 1 相比,使用方法 2 有什么缺点吗?

对于我的特定数据库,我使用了第二种方法,对于单个单词的简单查询,我似乎获得了合理的加速(搜索需要大约 1 秒)。但是,当我在函数中使用多个&|运算符进行复杂查询to_tsquery(并且表中只有大约 10 个匹配结果)时,搜索需要永远运行(许多小时)。如果我切换到方法 …

postgresql tsvector

3
推荐指数
1
解决办法
1175
查看次数

ghc wiki,未来功能和类型列表

当我看到这个非常有趣的例子时,我正在浏览关于TypeNatsGHC维基部分.他们正在创建类型列表:

type family Get (n :: Nat1) (xs :: [*]) :: *
type instance Get Zero     (x `: xs) = x
type instance Get (Succ n) (x `: xs) = Get n xs
Run Code Online (Sandbox Code Playgroud)

我想了解更多相关信息.我假设这个功能没有在7.6.1中实现(至少它不能为我编译),并且浏览门票证明是非常压倒性的.知道我应该寻找什么吗?

haskell ghc

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