Lets say I have a GADT for a language like so (my actual language is much more complex, about 50 constructors, but this is a simplified example): data Expr t where Add :: Expr t -> Expr t -> Expr t Sub :: Expr t -> Expr t -> Expr t Mult :: Expr t -> Expr t -> Expr t Negate :: Expr t -> Expr t Abs :: Expr t -> Expr t Scalar :: t -> Expr t Now lets define an
假设我有一个像这样的语言的GADT(我的实际语言要复杂得多,大约有50个构造函数,但这是一个简化的例子): data Expr t where Add :: Expr t -> Expr t -> Expr t Sub :: Expr t -> Expr t -> Expr t Mult :: Expr t -> Expr t -> Expr t Negate :: Expr t -> Expr t Abs :: Expr t -> Expr t Scalar :: t -> Expr t 现在让我们定义另一个数据类型,如下所示: data BinOpT = AddOp |
I'm trying to write a CSS DSL in Haskell, and keep the syntax as close to CSS as possible. One difficulty is that certain terms can appear both as a property and value. For example flex: you can have "display: flex" and "flex: 1" in CSS. I've let myself inspire by the Lucid API, which overrides functions based on the function arguments to generate either attributes
我正在尝试在Haskell中编写CSS DSL,并尽可能使语法尽可能靠近CSS。 一个难点是某些术语既可以作为属性又可以作为价值出现。 例如flex:你可以在CSS中使用“display:flex”和“flex:1”。 我让自己受到Lucid API的启发,它覆盖了基于函数参数的函数来生成属性或DOM节点(有时也会共享名称,例如<style>和<div style="..."> )。 无论如何,我遇到了一个问题,即GHC未能检查代码(Ambiguous类型变量)
Consider the following: {-# LANGUAGE TypeFamilies, FlexibleContexts, GADTs, MultiParamTypeClasses #-} type family F r class (Functor t) => T t r where fromScalar :: r -> t r data Foo t r where Foo :: t (F r) -> Foo t r Scalar :: r -> Foo t r toF :: r -> F r toF = undefined convert :: (T t (F r)) => Foo t r -> Foo t r convert (Scalar c) = let fromScalar' = fro
考虑以下: {-# LANGUAGE TypeFamilies, FlexibleContexts, GADTs, MultiParamTypeClasses #-} type family F r class (Functor t) => T t r where fromScalar :: r -> t r data Foo t r where Foo :: t (F r) -> Foo t r Scalar :: r -> Foo t r toF :: r -> F r toF = undefined convert :: (T t (F r)) => Foo t r -> Foo t r convert (Scalar c) = let fromScalar' = fromScalar in
Consider the following example: import Data.Constraint class Bar a where bar :: a -> a foo :: (Bar a) => Dict (Bar a) -> a -> a foo Dict = bar GHC has two choices for the dictionary to use when selecting a Bar instance in foo : it could use the dictionary from the Bar a constraint on foo , or it could use the runtime Dict to get a dictionary. See this question for an example wh
考虑下面的例子: import Data.Constraint class Bar a where bar :: a -> a foo :: (Bar a) => Dict (Bar a) -> a -> a foo Dict = bar 在foo选择Bar实例时,GHC有两种选择:它可以使用Bar a的字典或foo上Bar a约束,也可以使用运行时Dict获取字典。 请参阅此问题以查看字典对应于不同实例的示例。 GHC使用哪种字典?为什么它是“正确的”选择? GHC只挑选一个,这是正确的选择。 任何两个相同约束的字典
I'm using the syntactic library to work with ASTs. I'm getting some strange behavior, and I'm not what's happening. {-# LANGUAGE TypeOperators, GADTs, FlexibleInstances, FlexibleContexts, UndecidableInstances #-} module Foo where import Data.Syntactic import Data.Syntactic.Functional data Const a where Const :: Const (Full a) instance Render Const where renderSym Const = "
我正在使用语法库来处理AST。 我收到了一些奇怪的行为,而且我不是这样。 {-# LANGUAGE TypeOperators, GADTs, FlexibleInstances, FlexibleContexts, UndecidableInstances #-} module Foo where import Data.Syntactic import Data.Syntactic.Functional data Const a where Const :: Const (Full a) instance Render Const where renderSym Const = "const" main :: ASTF Const Int main = foo $ inj Const class Fo
Here is an example I wrote that uses if-else branches and guard expressions. When is one more appropriate over the other? The main reason I want to know this is because languages typically have a idiomatic way of doing things. test1 a b = if mod b 3 ≡ 0 then a + b else if mod b 5 ≡ 0 then a + b else a test2 a b | mod b 3 ≡ 0 = a + b | mod b 5 ≡ 0 = a + b | otherwise =
这是我写的一个使用if-else分支和警戒表达式的例子。 什么时候比另一个更合适? 我想知道这一点的主要原因是因为语言通常有一种习惯做事的方式。 test1 a b = if mod b 3 ≡ 0 then a + b else if mod b 5 ≡ 0 then a + b else a test2 a b | mod b 3 ≡ 0 = a + b | mod b 5 ≡ 0 = a + b | otherwise = a 你给的例子是警卫如何更好的一个很好的示范。 有了警卫,你有一个非常简单和可读的条件和
I've been messing around with the syntactic library (version 2.0 on github), and I have a small example that causes GHC(i) 7.6.2 to complain about IncoherentInstances . {-# LANGUAGE FlexibleInstances, TypeFamilies, TypeOperators, OverlappingInstances, UndecidableInstances, GADTs, FlexibleContexts, IncoherentInstances #-} import Data.Syntactic import Data.Syntactic.Functional type family
我一直在使用语法库(github上的2.0版本),我有一个小例子,它导致GHC(i)7.6.2抱怨IncoherentInstances 。 {-# LANGUAGE FlexibleInstances, TypeFamilies, TypeOperators, OverlappingInstances, UndecidableInstances, GADTs, FlexibleContexts, IncoherentInstances #-} import Data.Syntactic import Data.Syntactic.Functional type family FunToAST (dom :: * -> *) f type instance FunToAST dom (Full a) = AS
I'm doing so fairly fun stuff with GHC 7.8, but have ran in to a bit of a problem. I have the following: mkResultF :: Eq k => Query kvs ('KV k v) -> k -> ResultF (Reverse kvs) (Maybe v) mkResultF Here key = ResultComp (pure . lookup key) mkResultF q@(There p) key = case mkResultF p key of ResultFId a -> pure a ResultComp c -> ResultComp $ foo -> case
我用GHC 7.8做了相当有趣的事情,但遇到了一些问题。 我有以下几点: mkResultF :: Eq k => Query kvs ('KV k v) -> k -> ResultF (Reverse kvs) (Maybe v) mkResultF Here key = ResultComp (pure . lookup key) mkResultF q@(There p) key = case mkResultF p key of ResultFId a -> pure a ResultComp c -> ResultComp $ foo -> case c foo of ResultFId a -> pure a
There are lots of discussions of using unsafePerformIO carefully for global mutable variables, and some language additions to support it (eg Data.Global ). I have a related but distinct question: using it for global constant bindings. Here's a usage I consider entirely OK: command-line parsing. module Main where -----------------------------------------------------------------------------
对于全局可变变量使用unsafePerformIO以及支持它的一些语言补充(例如Data.Global ),有许多讨论。 我有一个相关但不同的问题:将其用于全局常量绑定。 以下是我认为完全正确的用法:命令行解析。 module Main where -------------------------------------------------------------------------------- import Data.Bool (bool) import Data.Monoid ((<>)) import Options.Applicative (short, help, execParser, inf
I have been reading through a Haskell d3js library: This is the code defining Haskell box: box :: Selector -> (Double,Double) -> St (Var' Selection) box parent (w,h) = do assign $ ((d3Root >>> select parent >>> func "append" [PText "svg"] >>> width w >>> height h >>> styl
我一直在阅读一个Haskell d3js库: 这是定义Haskell框的代码: box :: Selector -> (Double,Double) -> St (Var' Selection) box parent (w,h) = do assign $ ((d3Root >>> select parent >>> func "append" [PText "svg"] >>> width w >>> height h >>> style "background" "#eef") :: Chain