小编Reu*_*ben的帖子

为什么monad变换器与堆叠monad不同?

在许多情况下,我不清楚将两个monad与变压器组合而不是使用两个单独的monad可以获得什么.显然,使用两个独立的monad是一件麻烦事,并且可能涉及到符号内部的符号,但是有些情况下它只是表达不够吗?

一个案例似乎是列表上的StateT:组合monads不能得到正确的类型,如果你通过像Bar这样的monad栈获得正确的类型(其中Bar a =(Reader r(List(Writer w(Identity) a))),它没有做正确的事情.

但是我想更准确地理解monad变压器带来什么,当它们是否必要时,以及为什么.

为了使这个问题更加集中:

  1. 什么是没有相应变压器的monad的实际示例(这将有助于说明变压器可以做什么只是堆叠monad不能).
  2. StateT和ContT是唯一的变换器,它们给出的类型与m的组成不等同于m,对于底层monad m(无论它们是由哪个顺序组成的.)

(关于库的不同选择,我对特定的实现细节不感兴趣,而是对monad变换器/态射正在添加的一般问题(可能是Haskell独立)的问题,作为通过堆叠一堆monadic类型构造函数来组合效果的替代方法.)

(为了给出一点背景,我是一个语言学家,正在做一个丰富蒙塔古语法的项目 - 简单地输入lambda演算,用于将单词意义组成句子 - 用monad变换器堆栈.理解变换器是否真的在做真的很有帮助对我有用的任何东西.)

谢谢,

鲁本

monads haskell monad-transformers category-theory

21
推荐指数
2
解决办法
982
查看次数

有效地将大文件读入Map

我正在尝试编写代码以在Haskell中执行以下简单任务:使用此字典查找单词的词源,存储为大型tsv文件(http://www1.icsi.berkeley.edu/~demelo/etymwn/).我以为我会将tsv文件解析(使用attoparsec)到Map中,然后我可以根据需要使用它来高效地查找词源(并做一些其他的事情).

这是我的代码:

{-# LANGUAGE OverloadedStrings #-}

import Control.Arrow
import qualified Data.Map as M
import Control.Applicative
import qualified Data.Text as DT
import qualified Data.Text.Lazy.IO as DTLIO
import qualified Data.Text.Lazy as DTL
import qualified Data.Attoparsec.Text.Lazy as ATL
import Data.Monoid

text = do
    x <- DTLIO.readFile "../../../../etymwn.tsv"
    return $ DTL.take 10000 x

--parsers
wordpair = do
    x <- ATL.takeTill (== ':')
    ATL.char ':' *> (ATL.many' $ ATL.char ' ')
    y <- ATL.takeTill (\x -> x `elem` ['\t','\n'])
    ATL.char '\n' <|>   ATL.char …
Run Code Online (Sandbox Code Playgroud)

io performance haskell hashmap attoparsec

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

如何使用递归方案在Haskell中表达此概率分布

这个问题是部分理论/部分实施.背景假设:我使用monad-bayes库将概率分布表示为monad.分布p(a | b)可以表示为函数MonadDist m => b -> m a.

假设我有一个条件概率分布s :: MonadDist m => [Char] -> m Char.我想获得一个新的概率分布sUnrolled :: [Char] -> m [Char],在数学上(我认为)定义为:

sUnrolled(chars|st) = 
              | len(chars)==1 -> s st
              | otherwise -> s(chars[-1]|st++chars[:-1]) * sUnrolled(chars[:-1]|st)
Run Code Online (Sandbox Code Playgroud)

直觉是你采取得到分布st :: [Char],采样新的焦炭cs st,喂养st++[c]s,等等.我相信iterateM s或多或少是我想要的.为了使它成为我们实际可以看到的分布,让我们说如果我们击中某个角色,我们就会停下来.然后iterateMaybeM工作.

理论问题:由于各种原因,如果我能用更一般的术语来表达这种分布是非常有用的,例如,在给定随机余代数的情况下推广到树的随机构造的方式.看起来我在这里有某种变形(我意识到数学定义看起来像一个变形,但在代码中我想建立字符串,而不是将它们解构为概率)但我不能完全弄清楚细节,而不是至少是因为存在概率monad.

实际问题:例如,在Haskell中以使用递归方案库的方式实现它也是有用的.

recursion haskell probability category-theory recursion-schemes

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

简单地在Haskell中输入失败的lambda演算

我是Haskell的新手,如果这个问题没有多大意义,那么道歉.

我希望能够在Haskell中实现简单的类型化lambda表达式,当我尝试将表达式应用于另一个错误类型时,结果不是类型错误,而是一些设置值,例如Nothing.起初我以为使用Maybe monad会是正确的方法,但我无法得到任何工作.我想知道如果有的话,这是正确的方法.

问题的上下文,如果它有帮助,是我正在研究的项目,它将POS(词性)标签分配给句子中的单词.对于我的标签集,我使用的是分类语法类型; 这些是类型的lambda表达式,如(e -> s)or (e -> (e -> s)),where e和where s分别是名词和句子的类型.例如,kill有类型(e -> (e -> s))- 它需要两个名词短语并返回一个句子.我想写一个函数,它接受这些类型的对象列表,并找出是否有任何方法将它们组合以到达类型的对象s.当然,这正是Haskell的类型检查器所做的事情,因此为每个单词分配适当类型的lambda表达式应该很简单,让Haskell完成剩下的工作.问题是,如果s 无法达到,Haskell的类型检查器自然地阻止程序运行.

lambda haskell typed maybe

5
推荐指数
2
解决办法
579
查看次数