在许多情况下,我不清楚将两个monad与变压器组合而不是使用两个单独的monad可以获得什么.显然,使用两个独立的monad是一件麻烦事,并且可能涉及到符号内部的符号,但是有些情况下它只是表达不够吗?
一个案例似乎是列表上的StateT:组合monads不能得到正确的类型,如果你通过像Bar这样的monad栈获得正确的类型(其中Bar a =(Reader r(List(Writer w(Identity) a))),它没有做正确的事情.
但是我想更准确地理解monad变压器带来什么,当它们是否必要时,以及为什么.
为了使这个问题更加集中:
(关于库的不同选择,我对特定的实现细节不感兴趣,而是对monad变换器/态射正在添加的一般问题(可能是Haskell独立)的问题,作为通过堆叠一堆monadic类型构造函数来组合效果的替代方法.)
(为了给出一点背景,我是一个语言学家,正在做一个丰富蒙塔古语法的项目 - 简单地输入lambda演算,用于将单词意义组成句子 - 用monad变换器堆栈.理解变换器是否真的在做真的很有帮助对我有用的任何东西.)
谢谢,
鲁本
我正在尝试编写代码以在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) 这个问题是部分理论/部分实施.背景假设:我使用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],采样新的焦炭c从s st,喂养st++[c]回s,等等.我相信iterateM s或多或少是我想要的.为了使它成为我们实际可以看到的分布,让我们说如果我们击中某个角色,我们就会停下来.然后iterateMaybeM工作.
理论问题:由于各种原因,如果我能用更一般的术语来表达这种分布是非常有用的,例如,在给定随机余代数的情况下推广到树的随机构造的方式.看起来我在这里有某种变形(我意识到数学定义看起来像一个变形,但在代码中我想建立字符串,而不是将它们解构为概率)但我不能完全弄清楚细节,而不是至少是因为存在概率monad.
实际问题:例如,在Haskell中以使用递归方案库的方式实现它也是有用的.
recursion haskell probability category-theory recursion-schemes
我是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的类型检查器自然地阻止程序运行.
haskell ×4
attoparsec ×1
hashmap ×1
io ×1
lambda ×1
maybe ×1
monads ×1
performance ×1
probability ×1
recursion ×1
typed ×1