来自GHC 7.6 的文档:
[Y]你通常甚至不需要SPECIALIZE pragma.在编译模块M时,GHC的优化器(带-O)自动考虑在M中声明的每个顶级重载函数,并将其专门用于在M中调用它的不同类型.优化器还考虑每个导入的INLINABLE重载函数,并将其专门用于M中调用的不同类型.
和
此外,给定函数f的SPECIALIZE编译指示,GHC将自动为f调用的任何类型类重载函数创建特殊化,如果它们与SPECIALIZE编译指示位于同一模块中,或者它们是INLINABLE; 等等,过渡性的.
因此GHC应该自动专门化一些INLINABLE 没有编译指示标记的/大多数/所有(?)函数,如果我使用显式编译指示,则特化是可传递的.我的问题是:auto -specialization 是否具有传递性?
具体来说,这是一个小例子:
Main.hs:
import Data.Vector.Unboxed as U
import Foo
main =
let y = Bar $ Qux $ U.replicate 11221184 0 :: Foo (Qux Int)
(Bar (Qux ans)) = iterate (plus y) y !! 100
in putStr $ show $ foldl1' (*) ans
Run Code Online (Sandbox Code Playgroud)
Foo.hs:
module Foo (Qux(..), Foo(..), plus) where
import Data.Vector.Unboxed as U
newtype Qux r = Qux (Vector r)
-- …Run Code Online (Sandbox Code Playgroud) 什么是一些使用Haskell的开源程序,可以被认为是优质的现代Haskell?代码库越大越好.
我想从他们的源代码中学习.我觉得我已经超越了从小代码示例中学到的东西,这些代码通常是深奥的,小世界的.我想看看代码是如何构造的,当你有很多事情发生时,monad如何交互(日志记录,I/O,配置等).
我在函数式编程和PLT圈子中多次听到过"enggebras"这个术语,特别是在讨论对象,comonads,镜头等时.谷歌搜索这个术语给出了对这些结构进行数学描述的页面,这对我来说几乎是不可理解的.任何人都可以解释一下代数在编程环境中的意义,它们的意义是什么,以及它们与对象和共同体的关系?
haskell functional-programming scala category-theory recursion-schemes
这是场景:我已经编写了一些带有类型签名的代码,并且GHC抱怨无法推断x~y某些x和y.你通常可以将GHC作为一个骨骼并简单地将同构函数添加到函数约束中,但这有几个原因:
我只花了几个小时与案例3作斗争.我正在玩syntactic-2.0,我试图定义一个与域无关的版本share,类似于在中定义的版本NanoFeldspar.hs.
我有这个:
{-# LANGUAGE GADTs, FlexibleContexts, TypeOperators #-}
import Data.Syntactic
-- Based on NanoFeldspar.hs
data Let a where
Let :: Let (a :-> (a -> b) :-> Full b)
share :: (Let :<: sup,
Domain a ~ sup,
Domain b ~ sup,
SyntacticN (a -> (a -> b) -> b) fi)
=> a -> (a -> b) -> a
share = sugarSym Let
Run Code Online (Sandbox Code Playgroud)
和GHC could not …
我开始理解forall关键字如何在所谓的"存在类型"中使用,如下所示:
data ShowBox = forall s. Show s => SB s
Run Code Online (Sandbox Code Playgroud)
然而,这仅仅是如何forall使用的一个子集,我根本无法将其用于这样的事情:
runST :: forall a. (forall s. ST s a) -> a
Run Code Online (Sandbox Code Playgroud)
或解释为什么这些是不同的:
foo :: (forall a. a -> a) -> (Char, Bool)
bar :: forall a. ((a -> a) -> (Char, Bool))
Run Code Online (Sandbox Code Playgroud)
或整个RankNTypes东西......
我倾向于选择清晰,无术语的英语而不是学术环境中常见的语言.我尝试阅读的大部分解释(我可以通过搜索引擎找到的解释)存在以下问题:
runST,foo和bar以上).所以...
关于实际问题.任何人都可以完全解释的forall清晰,简单的英语关键字(或者,如果它存在于某个地方,点到我已经错过了这样一个明确的解释),不承担我在行话悠久的数学家?
编辑添加:
下面有高质量的答案有两个突出的答案,但不幸的是我只能选择一个最好的答案. 诺曼的回答很详细的和有用的,解释的方式,表现出一定的理论基础的东西forall,并在同一时间向我展示了一些它的实际影响. yairchu的回答覆盖了其他人没有提到的范围(范围类型变量),并用代码和GHCi会话说明了所有概念.我愿意选择两者是最好的.不幸的是,我不能和上,俯瞰着两个答案后密切,我已经决定,yairchu的稍微挤掉了诺曼,因为说明性代码和附加的说明.这是一个有点不公平,但是,因为我真的需要这两个答案,了解这一点是一点forall没给我留下了恐惧的隐隐感觉,当我看到它在类型签名.
什么是弱头范式(WHNF)是什么意思?什么是头标准型(HNF)和范式(NF)是什么意思?
熟悉的seq函数将表达式计算为我们称之为head normal form(缩写为HNF)的表达式.它一旦到达最外面的构造函数("头部")就会停止.这与正常形式(NF)不同,其中表达式被完全评估.
您还将听到Haskell程序员引用弱头正常形式(WHNF).对于正常数据,弱头正常形式与头部正常形式相同.差异只出现在功能上,而且我们在这里无关紧要.
我已经阅读了一些资源和定义(Haskell Wiki和Haskell邮件列表和自由词典),但我没有得到它.有人可能举一个例子或提供外行定义吗?
我猜它会类似于:
WHNF = thunk : thunk
HNF = 0 : thunk
NF = 0 : 1 : 2 : 3 : []
Run Code Online (Sandbox Code Playgroud)
如何做seq和($!)与WHNF和HNF有关?
我还是很困惑.我知道有些答案会忽略HNF.通过阅读各种定义,似乎WHNF和HNF中的常规数据之间没有区别.但是,它似乎与功能有所区别.如果没有差异,为什么还seq需要foldl'?
另一个混淆点来自Haskell Wiki,它指出seq减少到WHNF,并且对以下示例不做任何处理.然后他们说他们必须seq用来强迫评估.那不是强迫它到HNF吗?
常见的新手堆栈溢出代码:
Run Code Online (Sandbox Code Playgroud)myAverage = uncurry (/) . foldl' (\(acc, len) x -> (acc+x, len+1)) (0,0)了解seq和弱头正常形式(whnf)的人可以立即明白这里出了什么问题.(acc + x,len + 1)已经在whnf中,所以seq将值减少到whnf,对此无效.这段代码将像原始的foldl示例一样构建thunks,它们只是在元组内部.解决方案只是强制元组的组件,例如
Run Code Online (Sandbox Code Playgroud)myAverage …
代数数据类型的"代数"表达式对于具有数学背景的人来说非常具有启发性.让我试着解释一下我的意思.
定义了基本类型
•+X1并使用简写X²的X•X和2X对X+X等等,我们就可以定义如链表代数表达式
data List a = Nil | Cons a (List a) ↔ L = 1 + X • L
和二叉树:
data Tree a = Nil | Branch a (Tree a) (Tree a) ↔ T = 1 + X • T²
现在,我作为数学家的第一直觉是坚持这些表达方式,并试图解决L和T.我可以通过重复替换来做到这一点,但似乎更容易滥用符号,并假装我可以随意重新排列.例如,对于链接列表:
L = 1 + X • L
(1 - X) • L = 1
L = 1 …
ocaml haskell functional-programming algebraic-data-types miranda
我想在Haskell中学习FRP,但要确定要使用的库有点困难.许多似乎是死亡的尝试,有些似乎已经复活(例如最近在Yampa的活动).
根据我的阅读,似乎FRP有两种"种类":一侧是推拉式FRP(如Reactive-banana),另一侧是箭头式FRP(如Yampa).似乎在弗兰和弗里斯时代曾经有过一些"经典的FRP",但我没有发现其中的任何近期活动.
这两个(或三个)FRP真的是根本不同的方法吗?
其中一个是过时的理论而另一个是"未来的东西"?
或者它们是否必须并行发展,以满足不同的目的?
我是否列出了每个类别中最突出的图书馆,还是有其他选择要考虑(Sodium,Netwire等)?
我终于在J. Abrahamson的评论中看到了Evan Czaplicki的讲话.这非常有趣,并帮助我澄清了一些事情.我强烈推荐给发现这个问题的人.
haskell ×10
ghc ×3
monads ×2
coding-style ×1
constraints ×1
definition ×1
forall ×1
free-monad ×1
frp ×1
miranda ×1
ocaml ×1
open-source ×1
scala ×1
strictness ×1
syntax ×1
types ×1
yampa ×1