- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
András Kovács 提出了这个问题 in response to an answer to a previous question.
在用于各种类型的镜头式单板库中 * -> *
基于类
class Uniplate1 f where
uniplate1 :: Applicative m => f a -> (forall b. f b -> m (f b)) -> m (f a)
*
类型的类
class Uniplate on where
uniplate :: Applicative m => on -> (on -> m on) -> m on
contexts
的类似物?和
holes
, 两者的类型都是
Uniplate on => on -> [(on, on -> on)]
无需
Typeable1
?
Str
的老式单板库中实现。通过返回具有子项类型的类型级列表的结构来表示数据的结构。
(on, on -> on)
在
contexts
的签名中和
holes
data Hole f a where
Hole :: f b -> (f b -> f a) -> Hole f a
holes :: Uniplate1 f => f a -> [Hole f a]
...
holes
的实现。不需要
Typeable1
.
最佳答案
建议类型Hole
对函数的返回类型进行了不必要的限制。下面的类型可以代表之前的一切Hole
表示,以及更多,而不会丢失任何类型信息。
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
data Hole f a where
Hole :: f b -> (f b -> a) -> Hole f a
f a
, 我们可以使用
Hole f (f a)
来代表它。因为我们将使用
Hole
很多,最好有一些实用功能。因为
Hole
中函数的返回类型不再局限于
f
,我们可以制作一个
Functor
例如它
instance Functor (Hole f) where
fmap f (Hole b g) = Hole b (f . g)
contexts1
可以为
Hole
的任一版本编写通过替换 uniplate 库的
contexts
中元组的构造函数与
Hole
:
contexts1 :: Uniplate1 f => f a -> [Hole f (f a)]
contexts1 x = Hole x id : f (holes1 x)
where
f xs = [ Hole y (ctx . context)
| Hole child ctx <- xs
, Hole y context <- contexts1 child]
holes1
比较棘手,但仍然可以通过修改
holes
来实现来自
uniplate
图书馆。它需要一个新的
Replace1
Applicative
Functor
使用
Hole
而不是一个元组。元组的第二个字段被
second (f .)
修改。我们替换为
fmap f
对于
Hole
.
data Replace1 f a = Replace1 {replaced1 :: [Hole f a], replacedValue1 :: a}
instance Functor (Replace1 f) where
fmap f (Replace1 xs v) = Replace1 (map (fmap f) xs) (f v)
instance Applicative (Replace1 f) where
pure v = Replace1 [] v
Replace1 xs1 f <*> Replace1 xs2 v = Replace1 (ys1 ++ ys2) (f v)
where ys1 = map (fmap ($ v)) xs1
ys2 = map (fmap (f)) xs2
holes1 :: Uniplate1 f => f a -> [Hole f (f a)]
holes1 x = replaced1 $ descendM1 (\v -> Replace1 [Hole v id] v) x
decendM1
在
the preceding answer 中定义.
Replace
和
Replace1
可以统一;如何做到这一点在示例之后描述。
Hole
上的以下实用程序功能s 会很有用。
onHole :: (forall b. f b -> c) -> Hole f a -> c
onHole f (Hole x _) = f x
inHole :: (forall b. f b -> f b) -> Hole f a -> a
inHole g (Hole x f) = f . g $ x
example = If (B True) (I 2 `Mul` I 3) (I 1)
zero :: Expression b -> Expression b
zero x = case x of
I _ -> I 0
B _ -> B False
Add _ _ -> I 0
Mul _ _ -> I 0
Eq _ _ -> B False
And _ _ -> B False
Or _ _ -> B False
If _ a _ -> zero a
sequence_ . map (onHole print) . holes1 $ example
B True
Mul (I 2) (I 3)
I 1
sequence_ . map (onHole print) . contexts1 $ example
If (B True) (Mul (I 2) (I 3)) (I 1)
B True
Mul (I 2) (I 3)
I 2
I 3
I 1
sequence_ . map print . map (inHole zero) . contexts1 $ example
I 0
If (B False) (Mul (I 2) (I 3)) (I 1)
If (B True) (I 0) (I 1)
If (B True) (Mul (I 0) (I 3)) (I 1)
If (B True) (Mul (I 2) (I 0)) (I 1)
If (B True) (Mul (I 2) (I 3)) (I 0)
Replace
Applicative
Functor
可以重构,使其不知道任何
Uniplate
的孔的类型或
Uniplate1
, 而只知道孔是
Functor
.
Uniplate
的孔使用类型
(on, on -> a)
并且基本上使用
fmap f = second (f .)
;这是
(on, )
的组成和
on->
仿函数。
Compose
从转换器库中,我们将为
Hole
创建一个新类型对于
Uniplate
,这将使这里的示例代码更加一致和独立。
data Hole on a = Hole on (on -> a)
instance Functor (Hole on) where
fmap f (Hole on g) = Hole on (f . g)
Hole
从以前到
Hole1
.
data Hole1 f a where
Hole1 :: f b -> (f b -> a) -> Hole1 f a
instance Functor (Hole1 f) where
fmap f (Hole1 b g) = Hole1 b (f . g)
Replace
可以丢弃任何一种洞的所有知识。
data Replace f a = Replace {replaced :: [f a], replacedValue :: a}
instance Functor f => Functor (Replace f) where
fmap f (Replace xs v) = Replace (map (fmap f) xs) (f v)
instance Functor f => Applicative (Replace f) where
pure v = Replace [] v
Replace xs1 f <*> Replace xs2 v = Replace (ys1 ++ ys2) (f v)
where ys1 = map (fmap ($ v)) xs1
ys2 = map (fmap (f)) xs2
holes
和
holes1
可以根据新的
Replace
来实现.
holes :: Uniplate on => on -> [Hole on on]
holes x = replaced $ descendM (\v -> Replace [Hole v id] v) x
holes1 :: Uniplate1 f => f a -> [Hole1 f (f a)]
holes1 x = replaced $ descendM1 (\v -> Replace [Hole1 v id] v) x
关于haskell - 如何在镜头样式单板库中为更高种类的类型实现孔和上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25393870/
我正在为我的项目使用 Google Cloud Datastore(而非 NDB)。 python2.7 和 Django。 我想创建一个新模型,比如说 Tag 模型。 class Tag(db.Mo
我正在研究使用 monad 推导式来表示 SQL 查询,并生成适当的 SQL。乍一看,这不是问题,看起来很合适。但我必须限制类型,这些类型只能形成产品的单子(monad),而不是总和,而且我想不出一种
在Foldable文档,我看到以下实例: (Foldable f, Foldable g) => Foldable (Compose * * f g) 如果我查看 Compose 的定义,我看到它被声
给定一个团队->运动员关系并查询所有运动员。什么 我对fetch="Join"有误解吗?该映射是否应引起 通过联接加载团队?在对运动员进行迭代时 仍然懒惰地加载团队。 public class Ath
我才刚刚开始熟悉类型的概念,所以如果我没有很好地表达我的问题,请耐心等待...... 值有类型: 3 :: Int [1,2,3] :: [Int] ('c',True) :: (Char,Bool)
这里是我在 javascript 中的一个数组,效果很好! _rowData: [ { name: "Most Recent", view: "recentView" }, { nam
我正在尝试绘制 pandas Series用一条线。 这些线产生显示的输出和散点图。 import pandas as pd print(pd.__version__) ... print(type(
我正在使用 gcloud npm 模块。提前致谢。 我尝试了很多,但什么也没得到。 最佳答案 您需要对该实体进行查询并计算结果。 var query = ds.createQuery('EntityK
一些上下文 我对 libclang 不是很熟悉。我只是修改一个使用 the python bindings to libclang 的 vim 插件. 有一个 python 函数接收游标参数。当前 C
我有一个链接到 zlib v1.2.3 的程序,它出现以下错误: deflateEnd error 'no msg' kind: 'Z_DATA_ERROR': -3 该程序已成功处理许多要压缩的不同
我正在尝试通过遵循 the docs 来实现 log4rs .我的目标是将 info!("INFO") 的结果放入文件 requests.log,但出现错误: thread 'main' panick
Program type already present: org.apache.http.ContentTooLongException Message{kind=ERROR, text=Progr
当我执行 ng generate component faqs 时,我无法将新组件添加到我的 Nativescript 项目中它返回错误: Option "entryComponent" is dep
我是一名优秀的程序员,十分优秀!