天道酬勤,学无止境

Haskell 回避概率数据结构?(Haskell shying away from probabilistic data structures?)

问题

如果您搜索在 Haskell 中实现的跳过列表,您将不会找到很多。 它是一个需要随机数生成器的概率数据结构,这意味着这些结构中的任何一个都需要在 IO monad 中运行。

Haskell 的人是否因为不可能完全实现这些数据结构而远离这些数据结构? Haskell 如何处理它们?

回答1

伪随机数生成器当然可以在IO之外使用,只需将当前生成器值与概率纯数据结构一起存储并在构造修改版本时更新它。 这样做的缺点是,PRNG 比不纯的程序更具有确定性,因为单个数据结构之外的任何内容都不会更新它。 如果只有统计属性很重要,这不会造成问题,但否则可能会引起关注。

另一方面,在Ganesh Sittampalam的回答中,隐藏不纯的 PRNG 可以说是对unsafePerformIO的合理使用。 这公然违反​​了参考透明度,但仅限于 PRNG 将返回不可预测的、不一致的值——这就是重点! 但是,仍然需要小心,因为编译器可能会因为代码看起来很纯而做出错误的假设。

但实际上,这两种方法都不是非常吸引人。 使用unsafePerformIO令人不满意并且有潜在危险。 线程化 PRNG 状态很容易,但对使用它的任何计算都强加了(可能是虚假的)严格排序。 Haskell 程序员不会轻易放弃安全性和惰性(这是正确的!),当然,仅限于IO数据结构的效用有限。 因此,为了回答您的部分问题,这就是 Haskell 程序员可能会避免使用此类结构的原因。


至于“Haskell 如何处理”这样的事情,我建议这是一个错误的问题

真正归结为许多数据结构和算法隐含地假设(并优化)了一种命令式、不纯的、严格的语言,虽然在 Haskell 中实现这些当然是可能的,但它很少是可取的,因为(甚至忽略内部实现)使用它们会给您的代码强加一种非常不惯用的结构和方法。 此外,因为 Haskell 违反了那些隐含的假设,所以性能经常会下降(有时甚至很严重)。

需要意识到的是,算法和数据结构是一种手段,而不是目的。 这是很少的情况下,单一具体的实施需要-需要的一般的某些性能特性。 找到既提供所需特征又符合 Haskell 惯用的数据结构/算法几乎总是一个更好的计划,并且可能比尝试将严格的命令式钉子塞进一个懒惰的功能漏洞中表现得更好。

这种错误可能最常见于那些从未遇到过用哈希表无法解决的问题的程序员中,但对我们中的许多人来说,这个习惯很容易养成。 正确的方法是停止思考“我如何在 Haskell 中实现这个解决方案”,而是“在 Haskell 中解决我的问题的最佳方法是什么” 。 您可能会惊讶于答案的不同之处; 我知道我经常这样!

回答2

跳过列表可以纯粹实现——只需将当前种子封装在跳过列表本身的状态中。

data SkipList a = SkipList StdGen (Node a)
data Node a = ...

这可能会使您面临一些对“真实”跳过列表不切实际的复杂性攻击,因为您可以探测退化的插入顺序并针对同一种子重放攻击,但它可以让您在对抗性使用时获得结构的好处不是问题。

您还可以依靠unsafePerformIO和精心设计的无副作用的看似纯粹的界面。 诚然,它的内部并不纯净,但界面却给人以纯净的外观。

也就是说,跳过列表的许多经典性能优势来自它们可以非持久性实现的时候,这排除了功能接口。

回答3

由于跳过列表具有纯接口,因此在内部使用IO进行实现并将其包装为接口的unsafePerformIO将是有效的。 这只是将“正确处理”的负担从语言转移到程序员身上(这就是负担总是存在于不纯语言的地方)。

回答4

我曾经尝试过在 Haskell 中实现跳过列表。 当然,它是一个不可变的数据结构(毕竟这是 Haskell)。 但这意味着对随机性的需求消失了; “fromList”只是计算项目并为每个项目构建正确长度的跳过数组(每4个项目2个指针,每16个3个,每64个4个,等等)。

那时我意识到我只是在构建一个更复杂的树版本,而改变它的能力要少得多。 所以我放弃了。

回答5

随机生成器不需要IO操作。 它们遵循自己的 monadic 法则(有点源自State monad),因此可以通过Random monad 表示。

在跳过列表的情况下,您可以定义自己的能够进行概率计算的 monad,或者只使用标准的Random

demo :: Random Int
demo = do
 let l = SkipList.empty

 l2 <- l `add` ("Hello", 42)

 return $ l2 `get` "Hello"
回答6

有一个基于 STM for haskell 的新跳过列表实现,请参阅 hackage 上的 tskiplist。

回答7

好吧,首先,IO monad 中的随机数生成器是为了方便起见。 您可以在 IO monad 之外使用随机数生成器; 请参见 System.Random。 但是,是的,您确实需要维护状态; ST monad 在这里很有用。 而且,是的,我会说 Haskell 程序员更喜欢纯数据结构。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Haskell shying away from probabilistic data structures?
    If you search for skips lists implemented in Haskell, you won't find many. It is a probabilistic data structure needing a random number generator, meaning that any of these structures would need to run in the IO monad. Are Haskell folks staying away from these data structures because it's not possible to implement them purely? How can Haskell deal with them?
  • 如何在 Haskell 中编写 Data.Vector.Unboxed 实例?(How do I write a Data.Vector.Unboxed instance in Haskell?)
    问题 我有一个数值应用程序,它对概率的负对数做了很多工作,它(因为概率范围从零到一)取正双精度值或负无穷大(如果潜在概率为零)。 我将这些与 newtype Score ,如下所示: newtype Score = Score Double deriving (Eq, Ord) -- ^ A "score" is the negated logarithm of a probability negLogZero :: Score -- ^ Stands in for - log 0 negLogZero = Score 10e1024 negLogOne :: Score -- ^ - log 1 negLogOne = Score 0.0 unScore :: Score -> Double unScore (Score x) = x instance Show Score where show (Score x) = show x 现在,在 Viterbi 算法的实现中,我一直在使用Data.Vector ,确实我有一些Score的Data.Vector 。 在尝试进行一些性能调整时,我决定尝试使用Data.Vector.Unboxed 。 但是,我需要为Unbox编写一个实例,该实例无法派生,并且我无法弄清楚我需要做什么(特别是Unbox类型类的契约是什么)。
  • 什么是“无”?(What are Some and None?)
    问题 我使用Vec::get遇到了一些我不理解的输出。 这是代码: fn main() { let command = [('G', 'H'), ('H', '5')]; for i in 0..3 { print!(" {} ", i); println!("{:?}", command.get(i)); } } 输出是 0 Some(('G', 'H')) 1 Some(('H', '5')) 2 None 我之前涉猎过Haskell,这意味着我看了10分钟的教程站点,然后又回到了C ++,但是我记得为Haskell读过Some None存在》。 我很惊讶在Rust中看到这一点。 有人可以解释为什么.get()返回Some或None吗? 回答1 get的签名(对于切片,不是Vec ,因为您使用的是数组/切片)为 fn get(&self, index: usize) -> Option<&T> 也就是说,它返回一个Option,这是一个枚举,定义如下 pub enum Option<T> { None, Some(T), } None和Some是枚举的变体,也就是说,类型为Option<T>值可以是None ,也可以是包含T类型值的Some 。 您也可以使用变体来创建Option枚举: let foo = Some(42); let bar = None; 这与核心data
  • 什么是Levity多态性(What is Levity polymorphism)
    问题 正如问题的标题所示,我想知道什么是Levity多态性,其动机是什么? 我知道此页面上有一些细节,但是那里的大多数解释都超出了我的头脑。 :) 尽管此页面友好一些,但我仍然无法理解其背后的动机。 回答1 注意:此答案基于有关Levity讨论的最新观察结果。 有关Levity多态性的所有内容目前仅在GHC 8.0版本候选版本中实现,因此可能会发生变化(例如,参见#11471)。 TL; DR :这是一种使函数在提升类型和未提升类型上多态的方法,而常规函数则无法实现。 例如,由于Int#具有kind # ,因此以下代码不进行类型检查,因为Int#具有kind # ,但是id的type变量具有kind * : {-# LANGUAGE MagicHash #-} import GHC.Prim example :: Int# -> Int# example = id -- does not work, since id :: a -> a Couldn't match kind ‘*’ with ‘#’ When matching types a0 :: * Int# :: # Expected type: Int# -> Int# Actual type: a0 -> a0 In the expression: id 请注意, (->)仍然使用一些魔术。 在我开始回答这个问题之前
  • Haskell 与现实世界中的过程式编程 [关闭](Haskell vs. procedural programming in the real world [closed])
    问题 关闭。 这个问题是基于意见的。 它目前不接受答案。 想改善这个问题吗? 更新问题,以便通过编辑这篇文章用事实和引文来回答问题。 7年前关闭。 改进这个问题 这些天我开始认真地进行函数式编程。 虽然我对 Haskell 及其似乎提供的可能性感到非常兴奋,但现在我也可以看到它需要我花一些时间来学习。 在关于如何学习 Haskell 的 SO 问题中,答案指出要真正“掌握”它需要几个月甚至几年的时间。 现在,我知道 C、PHP、一些面向对象的东西等等。并且被告知 Haskell 在“现实世界”中并不常用,我是否会更好地提高我所知道的常规语言的技能? Haskell 值得奋斗吗? 在这个关于为什么人们认为函数式编程会流行的问题中,结论似乎是函数式编程会“流行”。 但是过程式编程肯定会保持领先,对吗? 编辑:keparo 很好地澄清了我的问题:与过程语言相反,学习 Haskell 和函数式编程范式对我有价值吗? 回答1 Haskell 并不像人们喜欢学习的那么难。 Haskell 为您打开了一个您从未知道的新世界。 学习与任何其他语言一样有价值。 您可能找不到要求您进行 Haskell 编程的工作,但这是否真的意味着一种语言没有价值? Haskell 会教你很多新东西,它会告诉你如何用你/做/使用的语言更好地编程。 您可以在空闲时间用它来做自己的个人项目。 如果将“现实世界”定义为
  • mplus必须始终具有关联性吗? Haskell Wiki与Oleg Kiselyov(Must mplus always be associative? Haskell wiki vs. Oleg Kiselyov)
    问题 Haskell Wikibook断言 要求MonadPlus的实例满足几个规则,就像要求Monad的实例满足三个monad法律一样。 ……最重要的是mzero和mplus构成一个monoid。 结果是, mplus必须是关联的。 Haskell Wiki同意。 但是,奥列格(Oleg)在他的许多回溯搜索实现之一中写道: -- Generally speaking, mplus is not associative. It better not be, -- since associative and non-commutative mplus makes the search -- strategy incomplete. 定义非关联的mplus是否mplus犹太mplus ? 前两个链接清楚地表明,如果mplus没有关联,则您没有真正的MonadPlus实例。 但是,如果Oleg这么做了……(另一方面,他只是在该文件中定义了一个名为mplus的函数,并且没有声称该mplus是mplus的MonadPlus 。他选择了一个非常令人困惑的名称,如果那是正确的解释。) 回答1 每个人都同意MonadPlus应该遵守的两个法律是身份和关联性法律(又称“半MonadPlus半律”): mplus mempty a = a mplus a mempty = a mplus (mplus
  • 如何在 Haskell 中制作异构列表? (最初在 Java 中)(How do I make an heterogeneous list in Haskell? (originally in Java))
    问题 如何将以下 Java 实现转换为 Haskell? 这里的主要目的是拥有一个包含各种元素的列表,这些元素是特定接口的子类型。 我试图在下面制作一个 Haskell 版本,但未能达到我的目的。 这里的要点是xs类型为[Bar]而不是Foo a => [a] 这是否意味着 Haskell 不能这样做,我应该换一种方式思考吗? 爪哇 interface Foo { void bar (); } public class Bar1 implements Foo { @Override public void bar() { System.out.println("I am bar 1 class"); } } public class Bar2 implements Foo { @Override public void bar() { System.out.println("I am bar 2 class"); } } public static void main(String[] args) { // The major purpose here is having a list // that contains elements which are sub-type of "Foo" List<Foo> ys = new ArrayList<Foo>(); Foo e1 =
  • OCaml 或 Haskell 中的机器学习?(Machine learning in OCaml or Haskell?)
    问题 我希望在新项目中使用 Haskell 或 OCaml,因为 R 太慢了。 我需要能够使用支持向量机,理想情况下将每个执行分开以并行运行。 我想使用函数式语言,而且我觉得就性能和优雅而言,这两种语言是最好的(我喜欢 Clojure,但在短期测试中它没有那么快)。 我倾向于 OCaml,因为它似乎对与其他语言的集成提供了更多支持,因此从长远来看它可能更适合(例如 OCaml-R)。 有没有人知道在 Haskell 或 OCaml 中进行这种分析的好教程或代码示例? 回答1 Hal Daume 在攻读博士学位期间编写了几个主要的机器学习算法。 (现在是机器学习界的助理教授和后起之秀) 在他的网页上,OCaml 中有一个 SVM、一个简单的决策树和一个逻辑回归。 通过阅读这些代码,您可以了解机器学习模型是如何在 OCaml 中实现的。 另一个编写基本机器学习模型的好例子是 OCaml 中用于科学和数值计算的 Owl 库。 我还想提一下 F#,一种类似于 OCaml 的新 .Net 语言。 这是一个用 F# 编写的因子图模型,用于分析国际象棋比赛数据。 这项研究也有 NIPS 出版物。 而FP适用于实现机器学习和数据挖掘模型。 但是你在这里最能得到的不是性能。 FP 比 C# 或 Java 等命令式语言更好地支持并行计算是正确的。 但是实现并行 SVM 或决策树与语言几乎没有关系!
  • 在 Haskell 中通过特殊类型类专门为 monad 绑定(Specializing bind for monads over special typeclasses in Haskell)
    问题 在 For a few Monads More 非常好的教程“Learn You a Haskell for a Great Good”的最后第二章中,作者定义了以下 monad: import Data.Ratio newtype Prob a = Prob { getProb :: [(a,Rational)] } deriving Show flatten :: Prob (Prob a) -> Prob a flatten (Prob xs) = Prob $ concat $ map multAll xs where multAll (Prob innerxs,p) = map (\(x,r) -> (x,p*r)) innerxs instance Monad Prob where return x = Prob [(x,1%1)] m >>= f = flatten (fmap f m) fail _ = Prob [] 我想知道是否可以在 Haskell 中专门化绑定运算符“>>=”,以防 monad 中的值属于像 Eq 这样的特殊类型类,因为我想将属于同一值的所有概率相加。 回答1 这称为“受限单子”,您可以这样定义它: {-# LANGUAGE ConstraintKinds, TypeFamilies, KindSignatures
  • haskell会擦除类型吗?(Does haskell erase types?)
    问题 Haskell会擦除类型吗?如果是,那么擦除类型与Java中发生的类型擦除有什么相似/不同? 回答1 警告:经验+推断。 请咨询同时使用两种编译器的人。 从某种意义上说,类型检查是在编译时完成的,类型系统的一些复杂功能被简化为更简单的语言结构,是的,但是与Java的方式截然不同。 类型签名不会产生运行时开销。 Haskell编译器擅长程序转换(它有更多的回旋余地,因为在许多情况下运行顺序不是由程序员指定的),并且可以自动内联适当的定义并将haskell-polymorhpic(= java-generic)函数专用于特定类型认为合适的话,如果有帮助的话。 这与Java类型擦除类似,但更多方面。 本质上,Haskell不需要类型强制转换来确保类型安全,因为Haskell从一开始就设计为类型安全的。 我们绝不求助于将一切都变成对象,也不会将其抛弃,因为多态(泛型)函数确实可以在任何数据类型上工作,无论是什么类型,指针类型或未装箱的整数,它都可以工作,没有诡计。 因此,与Java不同,强制转换不是编译多态(通用)代码的功能。 Haskell员工倾向于认为,如果要进行类型转换,无论如何您都会告别类型安全。 关于如何确保在编译时确保代码的静态类型正确性可以避免运行时开销的一个很好的例子,Haskell中有一个newtype构造,它是现有类型的类型安全包装器,并且已被完全编译掉
  • 是否存在类型受限的语言?(Is there a language with constrainable types?)
    问题 是否有一种类型化的编程语言,可以像下面的两个示例一样约束类型? 概率是一个浮点数,最小值为0.0,最大值为1.0。 type Probability subtype of float where max_value = 0.0 min_value = 1.0 离散概率分布是一个映射,其中:键都应该是相同的类型,值都应该是概率,并且值的总和= 1.0。 type DPD<K> subtype of map<K, Probability> where sum(values) = 1.0 据我了解,Haskell或Agda不可能做到这一点。 回答1 您想要的就是优化类型。 可以在Agda中定义Probability :Prob.agda 在第264行定义了具有求和条件的概率质量函数类型。 存在比Agda中的直接优化类型更多的语言,例如ATS 回答2 您可以在带有液体Haskell的Haskell中执行此操作,Liquid Haskell用细化类型扩展了Haskell。 谓词由SMT求解器在编译时进行管理,这意味着证明是全自动的,但您可以使用的逻辑受SMT求解器处理的逻辑的限制。 (幸运的是,现代的SMT求解器具有相当多的通用性!) 一个问题是我不认为Liquid Haskell当前支持浮点数。 如果不是这样,虽然,它应该是可能的纠正,因为有浮点数SMT求解器理论。
  • ()在Haskell中是什么意思(What does () mean in Haskell)
    问题 在一些Haskell代码中,我遇到了: put :: s -> m () ()在这里是什么意思? 我会使用搜索引擎,但是找不到正确处理()引擎。 回答1 如果不是怪异的特殊语法,则可以将其定义为 data () = () 这是最无聊的类型。 该语法应该使您想到元组: (a,b)是一个对, (a,b,c)是一个三元组,等等, ()是一个0元组。 唯一缺少的是一个1元组,它不能具有该语法,因为它会与通常使用的括号冲突。 ()经常被用作没有有趣结果的结果。 例如,应该执行某些I / O并在不产生结果的情况下终止的IO操作通常具有IO ()类型。 当您需要一些无趣的输入时,也可以使用它。 GHC为此具有特殊的语法,但是在Haskell 98中,模仿Lisp的cond方式如下: case () of () | c1 -> e1 | c2 -> e2 ... | otherwise -> e3 询问您拥有type ()值是完全有效的,但也很无聊; 您只能拥有一个合法的人。 从“几乎为Haskell的类别”的角度来看, ()是最终目标。 也就是说,对于任何类型X ,仅存在一个类型X -> ()合法函数,即const () 。 从另一个方向看, Void型养猪工人是一个最初的对象。 对于任何X类型,只有Void -> X类型的一个合法函数,即absurd 。 如果您想进行分类推理
  • 哈希数组映射树 (HAMT)(Hash Array Mapped Trie (HAMT))
    问题 我正在努力了解 HAMT 的细节。 为了理解,我自己用 Java 实现了一个。 我熟悉 Tries,我想我了解了 HAMT 的主要概念。 基本上, 两种类型的节点: 核心价值 Key Value Node: K key V value 指数 Index Node: int bitmap (32 bits) Node[] table (max length of 32) 为对象生成 32 位哈希。 一次遍历散列 5 位。 (0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-31)注意:最后一步(第7步)只有2位。 在每一步中,找到该 5 位整数在位图中的位置。 例如integer==5 bitmap==00001 如果该位为 1,则散列的该部分存在。 如果该位为 0,则密钥不存在。 如果键存在,通过计算位图中 0 和位置之间的 1 的数量,找到它在表中的索引。 例如integer==6 bitmap==0101010101 index==3 如果表指向键/值节点,则比较键。 如果该表指向一个索引节点,则转至 2 前进一步。 我不太明白的部分是碰撞检测和缓解。 在链接的论文中,他提到了它: 然后将现有密钥插入新的子哈希表并添加新密钥。 每使用 5 个以上的哈希位,冲突的概率就会降低 1/32。 有时可能会消耗整个 32 位散列
  • Safe modelling of relational data in Haskell
    I find it very common to want to model relational data in my functional programs. For example, when developing a web-site I may want to have the following data structure to store info about my users: data User = User { name :: String , birthDate :: Date } Next, I want to store data about the messages users post on my site: data Message = Message { user :: User , timestamp :: Date , content :: String } There are multiple problems associated with this data structure: We don't have any way of distinguishing users with similar names and birth dates. The user data will be duplicated on
  • 函数式编程是否要求新的命名约定?(Does functional programming mandate new naming conventions?)
    问题 我最近开始使用 Haskell 学习函数式编程,并在 Haskell 官方 wiki 上看到了这篇文章:如何阅读 Haskell。 文章声称x 、 xs和f等短变量名适合 Haskell 代码,因为它简洁且抽象。 从本质上讲,它声称函数式编程是一种独特的范式,以至于其他范式的命名约定不适用。 你对此有何看法? 回答1 在函数式编程范式中,人们通常不仅自顶向下,而且自底向上构建抽象。 这意味着您基本上增强了宿主语言。 在这种情况下,我认为简洁的命名是合适的。 Haskell 语言已经简洁而富有表现力,所以你应该习惯它。 但是,当尝试对某个域建模时,即使函数体很小,我也不相信简洁的名称是好的。 领域知识应该反映在命名中。 只是我的观点。 回应你的评论 我将从 Real World Haskell 中选取两个代码片段,都来自第 3 章。 在名为“更受控制的方法”的部分中,作者提出了一个函数,该函数返回列表的第二个元素。 他们的最终版本是这样的: tidySecond :: [a] -> Maybe a tidySecond (_:x:_) = Just x tidySecond _ = Nothing 由于类型参数a以及我们正在对内置类型进行操作的事实,该函数足够通用,因此我们并不真正关心第二个元素实际上是什么。 我相信在这种情况下x就足够了。 就像在一个小数学方程中一样。
  • 函数式编程语言如何工作?(How do functional programming languages work?)
    问题 如果函数式编程语言无法保存任何状态,它们将如何做一些简单的事情,例如从用户那里读取输入内容? 他们如何“存储”输入(或存储与此相关的任何数据?) 例如:这个简单的C语言将如何转换为Haskell这样的函数式编程语言? #include<stdio.h> int main() { int no; scanf("%d",&no); return 0; } (我的问题受到这篇出色的文章的启发:“名词的王国中的执行”。阅读该文章使我对面向对象的编程到底是什么,Java如何以一种极端的方式实现它以及函数式编程语言是如何实现的有了更好的理解。对比。) 回答1 如果函数式编程语言无法保存任何状态,它们将如何做一些简单的事情,例如从用户那里读取输入(我的意思是他们如何“存储”它)或为此存储任何数据? 正如您所收集的那样,函数式编程没有状态-但这并不意味着它不能存储数据。 区别在于,如果我按照 let x = func value 3.14 20 "random" in ... 我保证x的值在...始终是相同的:没有任何东西可以更改它。 同样,如果我有一个函数f :: String -> Integer (一个接受字符串并返回整数的函数),则可以确保f不会修改其参数,更改任何全局变量或将数据写入文件, 等等。 就像sepp2k在上面的评论中说的那样,这种不可变异性确实有助于推理程序:编写可折叠
  • Haskell FFI - 你能从 Haskell 数据结构中获得 C 指针吗?(Haskell FFI - can you obtain a C Pointer from a Haskell data structure?)
    问题 我有很多 C 结构,如 typedef struct { unsigned int a; unsigned int b; } StructA; 还有很多功能,比如 void doSomethingWith(StructA*,StructB*,StructC*); 有没有一种简单的方法可以使用 Haskell FFI 调用这些函数? 比如,是否有一些行为类似于 C 中的 & 运算符? (我想没有,但如果有,我想知道)。 我是否必须使 Haskell 端data的实例可存储(我没有这些结构的任何构造函数)。 另外:如果我必须传递结构而不是结构指针(不是假设性问题,我有一些类似的函数 - 这不是我的代码,所以我无能为力),我可以只传递结构呢? 就像我想打电话一样 void function(StructA); 我可以这样做吗 foreign import ccall "function" :: CUInt -> CUInt -> IO() ? 回答1 要将 Haskell 数据的引用传递给 C,其中内存分配在 Haskell 堆中,C 将直接对数据进行操作,您需要: 确保它在内存中具有正确的形状(通过将 A 映射到与StructA相同的字节结构的 Storable 实例)。 通过 mallocForeignPtr 在 Haskell 堆上分配和填充固定内存
  • Haskell大世界+思考
    文章目录 基石般灵活表现自由的抽象范式编程语言是什么? 推荐论文大佬建议MetaHaskell 实现类型系统语言抽象/模式问题解决方案 Haskell在工业界有哪些实际的应用?关于fp的一些思考递归是循环的超集。同样是a higher level of abstraction轮子封装。 世界运作的规律的更加高明的现实建模的抽象万花筒,就是编程语言百态的根本原因Haskell,你就是话题之王?令人敬畏的Haskell链接,框架,库和软件的辅助列表知识生态!DSL领域编程DSL编译原理翻译其他语言,语法解析器+模板编程+泛型编程模板template编程模板编程泛型编译器解析器paserHaskell LLVM JIT Compiler Tutorial并行并发语言扩展和程序标记ghc表一编译相关技巧Regex/文本处理/自然语言处理NLPlatex文本处理 快熬出头的Haskell大前端适合吗?网络编程优缺点 字符串网络编程serialize序列化/反序列化与泛型编程React App etc.Big Web ProductsA demo web browser engineThe intent is to develop a high quality, high level driver similar to pycassa.WSAMNetASM
  • Haskell是否真的是纯净的(是否有处理系统外部输入和输出的语言)?(Is Haskell truly pure (is any language that deals with input and output outside the system)?)
    问题 在就功能编程方面谈过Monad之后,此功能是否实际上使一种语言纯正,还是只是在黑板数学之外用于现实世界中计算机系统推理的另一种“摆脱监狱的卡”? 编辑: 这不是有人在这篇文章中所说的那样,而是一个真正的问题,我希望有人可以击倒我并说,证明,这是纯粹的。 我也在研究其他非纯函数语言和一些使用良好设计并比较纯净度的OO语言的问题。 到目前为止,在我非常有限的FP世界中,我仍然没有感到Monads的纯净,您会很高兴地知道,但是我喜欢不变性的想法,这在纯度方面至关重要。 回答1 使用以下迷你语言: data Action = Get (Char -> Action) | Put Char Action | End Get f表示:读取字符c ,然后执行动作fc 。 Put ca表示:写出字符c ,然后执行动作a 。 这是一个打印“ xy”的程序,然后询问两个字母并以相反的顺序打印它们: Put 'x' (Put 'y' (Get (\a -> Get (\b -> Put b (Put a End))))) 您可以操纵此类程序。 例如: conditionally p = Get (\a -> if a == 'Y' then p else End) 它的类型为Action -> Action它需要一个程序并给出另一个首先要求确认的程序。 这是另一个: printString =
  • 被多个数据结构引用时更新记录(Updating record when referenced by multiple data structures)
    问题 假设我有一条记录,例如Person ,并且我希望能够通过多个数据结构查找此人。 也许有一个按名称的索引,一个按人的邮政编码的索引,以及另一个按人当前的纬度和经度的索引。 也许还有更多的数据结构。 所有这些之所以存在,是因为我需要有效地查找一个或多个具有不同条件的人员。 如果我只需要阅读一个人的属性,这是没有问题的。 但是现在假设我需要使用这些数据结构之一查找一个人,然后更新该人的数据。 在OOP语言中,每个数据结构将指向内存中的同一个人。 因此,当您更新一个时,您也在隐式地更新其他数据结构的引用。 这几乎是对副作用和杂质的定义。 我知道这完全与Haskell范式背道而驰,而且我不希望Haskell这样工作。 那么,Haskell式的实现方式是什么? 明确地说,问题是这样的:我通过一个数据结构查找一个人,然后将该人(可能还有其他一些任意数据)传递给ArbitraryData -> Person -> Person类型的函数。 如何在所有各种查找结构中传播此更改? 作为Haskell的一个相对较新的人,我的第一个直觉是每次我更新一个人时,都用新更新的人来重建每个查找结构。 但这似乎是很多仪式,但我有很多机会以GHC无法检测到的方式搞砸,而且一点也不优雅。 Haskell以其优雅而著称,我无法想象它缺乏解决此类常见和基本问题的优雅解决方案。 所以我想我缺少了一些东西。 作为参考