Using ViewPatterns and PatternSynonyms to simply pattern matches

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

使用ViewPatterns和PatternSynonyms来简单地模式匹配

假设我有一个像这样的语言的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 |

GHC doesn't pick the only available instance

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

GHC不会选择唯一可用的实例

我正在尝试在Haskell中编写CSS DSL,并尽可能使语法尽可能靠近CSS。 一个难点是某些术语既可以作为属性又可以作为价值出现。 例如flex:你可以在CSS中使用“display:flex”和“flex:1”。 我让自己受到Lucid API的启发,它覆盖了基于函数参数的函数来生成属性或DOM节点(有时也会共享名称,例如<style>和<div style="..."> )。 无论如何,我遇到了一个问题,即GHC未能检查代码(Ambiguous类型变量)

Monomorphism restriction triggered when generic instance defined

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

Which dictionary does GHC choose when more than one is in scope?

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

GHC选择何种字典时,多于一个字典?

考虑下面的例子: 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只挑选一个,这是正确的选择。 任何两个相同约束的字典

Strange behavior when adding constraint to instance

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

When are guard expressions appropriate?

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 你给的例子是警卫如何更好的一个很好的示范。 有了警卫,你有一个非常简单和可读的条件和

XIncoherentInstances doesn't work

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

XIncoherentInstances不起作用

我一直在使用语法库(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

How can I extract this polymorphic recursion function?

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

Haskell: use of unsafePerformIO for global constant bindings

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 -----------------------------------------------------------------------------

Haskell:使用unsafePerformIO进行全局常量绑定

对于全局可变变量使用unsafePerformIO以及支持它的一些语言补充(例如Data.Global ),有许多讨论。 我有一个相关但不同的问题:将其用于全局常量绑定。 以下是我认为完全正确的用法:命令行解析。 module Main where -------------------------------------------------------------------------------- import Data.Bool (bool) import Data.Monoid ((<>)) import Options.Applicative (short, help, execParser, inf

How do the operators `>>>` and `>>=` work in Haskell?

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中运算符`>>>`和`>> =`如何工作?

我一直在阅读一个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