我遇到过对Haskell的引用Data.Typeable,但我不清楚为什么我想在我的代码中使用它.
它解决了什么问题,怎么解决?
haskell generic-programming typeclass scrap-your-boilerplate
我一直在使用用Haskell编写的Elm编译器.
我想开始为它实现一些优化,其中一部分涉及遍历AST并向某些节点添加"注释",例如尾调用等.
我知道我可以使用SYB或uniplate进行遍历,但我想知道是否有一种无样板的方法来处理类型.
所以,假设我们的AST有一堆代数类型:
data Expr = PlusExpr Expr Expr ...
data Def = TypeAlias String [String] Type ...
Run Code Online (Sandbox Code Playgroud)
如果我正在编写样板文件,我会创建这样的新类型:
data AnnotatedExpr = PlusExpr Expr Expr [Annotation] ...
data AnnotatedDef = TypeAlias String [String] Type [Annotation] ...
Run Code Online (Sandbox Code Playgroud)
这是很多写的boilderplate,并且似乎是避免这种做法的好习惯.
我可以这样写:
Data AnnotationTree = Leaf [Annotation]
| Internal [AnnotationTree] [Annotation]
Run Code Online (Sandbox Code Playgroud)
然后我就会有一个与AST并行运行的注释树.但是不能保证这些树具有相同的结构,因此我们失去了类型安全性.
所以我想知道,是否有一个优雅/推荐的解决方案,以避免样板,但仍然以类型安全的方式注释树?要用等效的节点替换每个节点,还有稍后将在编译中使用的注释列表?
haskell generic-programming ghc scrap-your-boilerplate template-haskell
gfoldl
:: (Data a)
=> (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> a
-> c a
Run Code Online (Sandbox Code Playgroud)
有什么目的c和c (d -> b)它吗?为什么它不仅仅是一个常规的折叠,类似于
gfoldl'
:: (Data a)
=> (forall d. Data d => r -> d -> r)
-> r
-> a
-> r
Run Code Online (Sandbox Code Playgroud) 我看到有人在讨论Scrap Your Boilerplate和Haskell中的泛型编程.这些术语是什么意思?我什么时候想要使用Scrap Your Boilerplate,我该如何使用它?
haskell functional-programming generic-programming scrap-your-boilerplate
我在Haskell中找到了一个有趣的库,它基于Simon Peyton Jones的论文,称为Scrap Your Boilerplate,它似乎是编写可以在函数式编程语言中更新大型深度嵌套数据结构的代码的有效方法.它使代码如下:
incS :: Float -> Salary -> Salary
incS k (S s) = S (s * (1+k))
increase :: Float -> Company -> Company
increase k = everywhere (mkT (incS k))
Run Code Online (Sandbox Code Playgroud)
在一个潜在的庞大而复杂的公司数据结构中,每个人都有效地增加了固定比例k的工资.
在Clojure中是否有相同的库或方法来实现相同类型的编程风格?
例如,我如何编写上面使用的示例的Clojure等价物:
(defn increase [company k]
(everywhere-in company (transform-map-values :salary #(* % (+ 1 k))))
Run Code Online (Sandbox Code Playgroud) 我正在努力学习GHC Generics.在回顾了几个例子后,我想尝试创建一个通用Functor实例(忽略GHC可以为我自动派生它们).但是,我意识到我不知道如何使用Generics处理参数化数据类型,我见过的所有例子都很实用*.这是可能的,如果是的话,怎么样?(我也对其他类似的框架感兴趣,比如SYB.)
在Scrap中你的样板重新加载,作者描述了一个新的Scrap Your Boilerplate演示文稿,它应该与原版相同.
然而,一个不同之处在于它们假设一组有限的,基本的"基础"类型,用GADT编码
data Type :: * -> * where
Int :: Type Int
List :: Type a -> Type [a]
...
Run Code Online (Sandbox Code Playgroud)
在原始SYB中,使用类型安全转换,使用Typeable类实现.
我的问题是:
我有一个类型类Cyclic,我希望能够提供泛型实例.
class Cyclic g where
gen :: g
rot :: g -> g
ord :: g -> Int
Run Code Online (Sandbox Code Playgroud)
给定一个类型的nullary构造函数,
data T3 = A | B | C deriving (Generic, Show)
Run Code Online (Sandbox Code Playgroud)
我想生成一个等效于此的实例:
instance Cyclic T3 where
gen = A
rot A = B
rot B = C
rot C = A
ord _ = 3
Run Code Online (Sandbox Code Playgroud)
我试图找出所需的Generic机器
{-# LANGUAGE DefaultSignatures, FlexibleContexts, ScopedTypeVariables, TypeOperators #-}
import GHC.Generics
class GCyclic f where
ggen :: f a
grot :: f a …Run Code Online (Sandbox Code Playgroud) 与GHC Generics相比,是否只有SYB可以完成任务,或者使用它更容易?
我有一个与Show相同的类,我想为每个元组类型创建一个这个类的实例.通常,这是通过为每个元组类型单独写入实例来完成的
instance (Show a, Show b) => Show (a,b) where
showsPrec _ (a,b) s = show_tuple [shows a, shows b] s
instance (Show a, Show b, Show c) => Show (a, b, c) where
showsPrec _ (a,b,c) s = show_tuple [shows a, shows b, shows c] s
instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
showsPrec _ (a,b,c,d) s = show_tuple [shows a, shows b, shows c, shows d] s …Run Code Online (Sandbox Code Playgroud) haskell ×10
generics ×2
ghc ×2
ghc-generics ×2
boilerplate ×1
clojure ×1
deriving ×1
typeclass ×1
types ×1