小编Dav*_*vid的帖子

什么是免费monad?

我见过的长期免费单子弹出每一个 现在 随后一段时间,但每个人似乎只是使用/讨论这些问题没有给予它们是什么解释.所以:什么是免费的monads?(我会说我熟悉monad和Haskell的基础知识,但对类别理论只有非常粗略的了解.)

monads haskell free-monad

357
推荐指数
7
解决办法
5万
查看次数

ST monad是如何工作的?

我知道ST monad就像是IO的小兄弟,后者又是带有RealWorld魔法的状态monad .我可以想象状态,我可以想象RealWorld以某种方式被放入IO,但每次我写一个ST monad 的类型签名都STs我感到困惑.

举个例子吧ST s (STArray s a b).s那里的工作如何?它是否仅用于在计算之间建立一些人工数据依赖性,而不能像状态monad中的状态那样被引用(由于forall)?

我只是抛出想法,真的很感谢比我更有知识的人向我解释.

monads haskell

68
推荐指数
2
解决办法
9429
查看次数

为什么Haskell中没有IO变压器?

每个其他monad都带有变压器版本,据我所知,变压器的概念是monad的通用扩展.跟随其他变形金刚的构建方式,IOT就像是

newtype IOT m a = IOT { runIOT :: m (IO a) }
Run Code Online (Sandbox Code Playgroud)

我可以在现场组成有用的应用程序:IOT Maybe可以执行IO操作,IOT []也可以不执行任何操作,可以构建一个稍后可以执行的列表sequence.

那么为什么Haskell中没有IO变压器呢?

(注意:我在Haskell Cafe上看过这篇文章,但对它没有多大意义.另外,ST转换器的Hackage页面在其描述中提到了一个可能相关的问题,但没有提供任何细节.)

io monads haskell monad-transformers

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

Haskell程序如何在内部编译和执行?

我无法理解Haskell(GHC)如何编译程序,以及这些程序是如何运行的.

  1. GHC是用Haskell编写的一个非平凡程序的典型例子.但是,GHC的某些部分似乎不是用Haskell编写的,即运行时环境(在C/C--中).这是为什么?表现原因?(我知道这个网站及其朋友,但对它们没有多大意义.)
  2. 说到运行时环境:为什么编译语言需要一个?编译的程序不应该是机器代码而不是别的吗?根据我的理解,运行时环境有点类似于虚拟机或字节码解释器,它处理某种形式的元代码并基于此进行实际计算.那么:GHC运行时到底做了什么,为什么首先需要呢?
  3. 关于FFI:如何处理C呼叫?最初,我认为使用FFI生成单个可执行文件,其中Haskell和C一起编译.但是,我多次读过GHC程序对程序执行C语言调用.这对于理解FFI与并行编程的问题尤为相关.那么:FFI功能与普通的Haskell功能有何不同?

haskell runtime compilation ghc

31
推荐指数
3
解决办法
7479
查看次数

为什么Haskell/GHC可执行文件在文件大小中如此之大?

可能重复:
用GHC编译成小二进制的小Haskell程序

最近我注意到Haskell可执行文件有多大.下面的所有内容都是-O2在Linux 上用GHC 7.4.1编译的.

  1. Hello World(main = putStrLn "Hello World!")超过800 KiB.strip在它上面运行会将文件大小减少到500 KiB; 甚至添加-dynamic到编译中也没有多大帮助,让我在400 KiB附近删除了一个可剥离的可执行文件.

  2. 编译涉及Parsec的非常原始的示例产生1.7 MiB文件.

    -- File: test.hs
    import qualified Text.ParserCombinators.Parsec as P
    import Data.Either (either)
    
    -- Parses a string of type "x y" to the tuple (x,y).
    testParser :: P.Parser (Char, Char)
    testParser = do
        a <- P.anyChar
        P.char ' '
        b <- P.anyChar
        return (a, b)
    
    -- Parse, print result.
    str = "1 2"
    main = print $ …
    Run Code Online (Sandbox Code Playgroud)

haskell compilation ghc

16
推荐指数
2
解决办法
4464
查看次数

有懒惰/严格版本的Writer有什么意义?

为什么Haskell中有两个不同的Writer类型monad?直觉上,读"严格的作家monad"意味着<>严格,所以日志中没有thunk积累.但是,查看源代码,事实证明并非如此:

-- Lazy Writer
instance (Monoid w, Monad m) => Monad (WriterT w m) where
-- ...
m >>= k  = WriterT $ do
    ~(a, w)  <- runWriterT m
    ~(b, w') <- runWriterT (k a)
    return (b, w <> w')
Run Code Online (Sandbox Code Playgroud)

在严格的版本中,模式不是无可辩驳的,即~缺失.所以上面发生的是,m并且k a没有评估,但存储为thunk.在严格版本中,它们被评估以检查它们是否与元组模式匹配,结果被馈送到<>.在这两种情况下,在>>=实际需要产生的值之前不会对其进行评估.所以我理解它的方式是懒惰和严格版本都做同样的事情,除了它们在定义中的不同位置有thunk >>=:lazy产生runWriterTthunks,strict产生<>thunk.

这让我有两个问题:

  1. 是上面的权利,还是我在这里误解了评价?
  2. 我可以在<>不编写自己的包装器和实例的情况下完成严格吗?

monads haskell writer monad-transformers

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

为什么Cabal没有成为一名完整的包裹经理?

(在我开始之前:我将使用Cabal for Everything,其名称中包含Cabal并与Haskell有关.)

有了通常的"你需要更新X来安装Y,但这会打破依赖性Z"问题,前几天,我想我只是问:为什么Cabal不是设计成一个完整的包管理器,特别是以下功能:

  • 版本控制:将软件包的多个版本并排安装,让软件包选择所需的依赖项.如果未指定包版本,请使用最新版本.
  • 更新软件包 - 或更好,安装最新版本.
  • 删除
  • 检查包装完整性

你会看到这个列表的去向.现在,对我来说,Cabal感觉就像一个有点复杂的构建系统(当你想第一次开始使用它时,试着找出你的软件包所需的Base版本),这是一个半生不熟的软件包安装程序.

所以问题再次出现:为什么Cabal没有制作全功能的构建/包装系统?我确信有一些设计决定导致当前状态.

(这个问题在某种程度上受到了对Reddit的咆哮的启发,但与那个人相反并不意味着冒犯任何人.):-)

haskell cabal cabal-install

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

并行排序IO操作

我有一个返回IO动作的函数,

f :: Int -> IO Int
Run Code Online (Sandbox Code Playgroud)

我想为参数的多个值并行计算这个函数.我天真的实施如下:

import Control.Parallel.Strategies

vals = [1..10]
main = do
      results <- mapM f vals
      let results' = results `using` parList rseq
      mapM_ print results'
Run Code Online (Sandbox Code Playgroud)

我给这理由是,第一mapM结合型的东西IO [Int]results,results'应用并行的策略所包含的名单,并mapM_通过打印,最后请求的实际值-但究竟是要打印并行已经引起的,所以程序应并行.

在确实使用了我所有的CPU之后感到高兴,我注意到程序在运行时效果较差(如挂钟时间),而+RTS -N8不是没有任何RTS标志.我能想到的唯一解释是,第一个mapM必须排序 - 即执行 - 所有IO操作已经,但这不会导致无效,但使N8执行与非平行的一样有效,因为所有的工作都由主线程.以+RTS -N8 -s收益率运行程序SPARKS: 36 (11 converted, 0 overflowed, 0 dud, 21 GC'd, 4 fizzled),这肯定不是最优的,但不幸的是我无法理解它.

我想我已经在Haskell并行化或IO monad的内部找到了初学者的垫脚石之一.我究竟做错了什么?

背景信息:f n是一个返回Project Euler问题n的解决方案的函数.由于其中许多都有要读取的数据,因此我将结果放入IO monad中.它看起来如何的一个例子是 …

io parallel-processing haskell

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

QuickCheck 2批处理

QuickCheckBatch模块已被删除,版本2(1.2.0.1仍然有它).因此,我总是觉得 - mapM_在一起进行多项测试是一种hacky.我是否忽略了QuickCheck 2中的后续功能?是否存在将独立测试组合在一起的规范方法?

haskell quickcheck batch-processing

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

如何在Data.Set中插入O(log(n))?

在查看文档时Data.Set,我看到在树插入元素被称为O(log(n)).但是,我会直观地期望它是O(n*log(n))(或者可能是O(n)?),因为参照透明度需要在O(n)中创建前一个树的完整副本.

据我所知,例如(:)可以将O(1)代替O(n),因为这里不必复制完整列表; 新的列表可以由编译器优化为第一个元素加上指向旧列表的指针(请注意,这是一个编译器 - 而不是语言级别 - 优化).但是,在a中插入一个值Data.Set涉及重新平衡,这对我来说非常复杂,我怀疑有类似于列表优化的东西.我尝试阅读Set docs引用的论文,但无法用它来回答我的问题.

那么:如何在一个(纯)函数式语言中将元素插入二叉树中是O(log(n))?

complexity-theory haskell referential-transparency

8
推荐指数
2
解决办法
610
查看次数