- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 Haskell 新手。我正在尝试在 Haskell 中创建一种迷你语言,并且希望如果可能的话有一个名为 opp
(“opposite”的缩写)的高阶函数,它将许多熟悉的函数转换为它们明显的函数对立面。例如,opp succ
将是函数 pred
,opp head
将是 last
,依此类推。对于将函数转换为相反函数的含义,我没有一些一般性定义:我只想挑选几个关键示例并声明它们的相反函数。所以我想要一个几乎从未定义的高度多态函数。
困难似乎在于我想通过名称而不是其本质(可以这么说)来识别函数。这种困难的一个表现是,如果我写
opp succ = pred
然后 Haskell 将 succ
视为变量,因此给我一个常量函数,该函数始终采用值 pred
。我真正想说的是,“如果您看到字符串 opp succ
,那么可以将其视为 pred
的另一个名称。”但经过一段时间的搜索后,我不知道如何做到这一点(如果可能的话)。
总而言之,我想定义一个函数
opp::(a -> b) -> (a -> b)
通过说类似的话
opp succ = pred
opp pred = succ
opp head = 最后
opp 最后 = 头
只要我愿意,就可以添加到这个列表中。显然我不能那样做,但是有没有一些不可怕的方法可以达到相同的效果?
最佳答案
是的,你可以,但是你需要 RankNTypes 才能有一个好的实现。
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE RankNTypes #-}
module Opposites where
class Opposite f where
makeOpposite :: (a -> b) -> (a -> b) -> f a b
data FunctionAndOpposite a b = FunctionAndOpposite (a -> b) (a -> b)
instance Opposite (->) where
makeOpposite = const
instance Opposite FunctionAndOpposite where
makeOpposite = FunctionAndOpposite
opp :: FunctionAndOpposite a b -> a -> b
opp (FunctionAndOpposite _ f) = f
type a :<-> b = forall f. Opposite f => f a b
succ' :: Enum a => a :<-> a
succ' = makeOpposite succ pred
pred' :: Enum a => a :<-> a
pred' = makeOpposite pred succ
head' :: [a] :<-> a
head' = makeOpposite head last
last' :: [a] :<-> a
last' = makeOpposite last head
使用示例:
> head' [1,2,3]
1
> opp head' [1,2,3]
3
工作原理
首先是Opposite
类(class)。这只是描述了一个f a b
可以由 (a -> b)
的两个函数构造而成(正常和相反的功能)。
接下来是数据类型 FunctionAndOpposite
被定义为。这仅存储两个函数。现在标准函数和 this 都是类的实例 Opposite
。函数实例只是丢弃相反的函数。
现在是opp
可以定义函数。这只是从 FunctionAndOpposite
中取出第二个函数。 .
最后我们得到了将所有内容组合在一起的行:
type a :<-> b = forall f. Opposite f => f a b
它定义的是一个类型同义词,它接受两个输入类型 a 和 b,然后返回类型 f a b
,其中f
可以是任何Opposite
(取决于需要什么)。
( :<->
只是使用 TypeOperators
启用的类型的一个奇特名称)。
考虑代码 head' [1,2,3]
。 head'
类型为 forall f. Opposite f => f [a] a
。但是,由于它被用作函数应用程序(因为它之后有一个参数),f
必须是->
。因此,Opposite
的函数实现使用时,将第一个参数返回给 makeOpposite
,即head
(太棒了!)。
但是,可以说 opp head' [1,2,3]
叫做。 opp
类型为 FunctionAndOpposite a b -> a -> b
,所以f
必须是FunctionAndOpposite
。因此,FunctionAndOpposite
Opposite
的实例被调用,使用 makeOpposite
的两个参数创建数据类型。 opp
然后提取第二个函数,即 last
.
顺便说一句,这是使用 lens
中使用的类似技术来完成的。 Isomorphism
的库。同构基本上是一对互为逆的函数。例如(+2)
和(-2)
, reverse
和它本身。一般来说,这可能是一个更有用的概念,因为它允许您通过转换对数据类型运行操作。请参阅Control.Lens.Iso有关更多详细信息,但请注意,要理解这一点,您需要了解镜头概念,这是一项相当大的工作。
关于haskell - 是否可以根据具体情况定义高阶 "opposite"函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24241367/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!