这个功能可以用 Haskell 的类型系统来实现吗?
在 Scala 中,集合上的高阶操作总是返回上下文中可能的最佳类型。例如,在 BitSet
的情况下,如果将整数映射到整数,您将得到一个 BitSet
,但如果您将整数映射到字符串,您将得到一个通用的 Set< /代码>。同样,如果您使用生成一对的函数来
映射
一个Map
,那么您将得到一个Map
作为回报。否则你会得到一个简单的Iterable
。 Map 结果的静态类型和运行时表示都取决于传递给它的函数的结果类型。
scala> Map(2 -> 'a', 6 -> 'b') map { case (k, v) => (k + 1, v.toString) }
res0: scala.collection.immutable.Map[Int,java.lang.String] = Map(3 -> a, 7 -> b)
scala> Map(2 -> 'a', 6 -> 'b') map { _._1 }
res1: scala.collection.immutable.Iterable[Int] = List(2, 6)
scala> import collection.immutable.BitSet
import collection.immutable.BitSet
scala> BitSet(2, 44, 93).map(1 +)
res3: scala.collection.immutable.BitSet = BitSet(3, 45, 94)
scala> BitSet(2, 44, 93).map(_ + "hola")
res4: scala.collection.immutable.Set[String] = Set(2hola, 44hola, 93hola)
是否可以在 Haskell 的类型系统中实现相同的功能?如果是,怎么办?如果能对上述代码片段中的示例进行 Haskell 翻译,我们将不胜感激。 :-)
In Scala, the higher order operations on collections always return the best possible type in the context. For example, in case of BitSet
, if you map ints to ints you get a BitSet
, but if you map ints to strings, you get a general Set
. Similarly, if you map
a Map
with a function that yields a pair, then you get a Map
in return. Else you get a simple Iterable
. Both the static type and the runtime representation of map's result depend on the result type of the function that's passed to it.
scala> Map(2 -> 'a', 6 -> 'b') map { case (k, v) => (k + 1, v.toString) }
res0: scala.collection.immutable.Map[Int,java.lang.String] = Map(3 -> a, 7 -> b)
scala> Map(2 -> 'a', 6 -> 'b') map { _._1 }
res1: scala.collection.immutable.Iterable[Int] = List(2, 6)
scala> import collection.immutable.BitSet
import collection.immutable.BitSet
scala> BitSet(2, 44, 93).map(1 +)
res3: scala.collection.immutable.BitSet = BitSet(3, 45, 94)
scala> BitSet(2, 44, 93).map(_ + "hola")
res4: scala.collection.immutable.Set[String] = Set(2hola, 44hola, 93hola)
Is it possible to implement the same functionality in Haskell's type system? If yes, how? A Haskell translation of the examples in above code snippet would be much appreciated. :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不认为你的第一个例子很 Haskell-y,因为你重载了同一个名字来做两件截然不同的事情。在 Haskell 中,当您将函数映射到某个容器时,您希望得到相同的容器类型。事实上,这在 Haskell 中非常常见,以至于有一个类型类,
Functor
封装了这种模式。Haskell 中所有形式的重载都归结为使用类型类,虽然您可以使用它们来实现类似的功能,但与仅使用只做您想要的一件事的普通函数相比,它会非常做作并且没有多大用处。
我认为你的第二个例子与 Haskell 更相关,因为它更多的是根据所包含的类型选择最有效的数据结构实现,并且我怀疑使用 类型族,但我对这些不太熟悉,所以我会让其他人尝试回答这部分。
I don't think your first example is very Haskell-y, as you're overloading the same name to do two very different things. In Haskell, when you map a function over some container, you expect to get the same container type back. In fact, this is so common in Haskell that there is a type class,
Functor
which encapsulates this pattern.All forms of overloading in Haskell boil down to using type classes, and while you could use those to achieve something similar, it would be very contrived and not very useful over just using plain functions that do just the one thing you want.
I think your second example is more relevant to Haskell, as it's more about picking the most efficient implementation of a data structure based on the contained type, and I suspect this shouldn't be too difficult to do using type families, but I'm not too familiar with those, so I'll let someone else try to answer that part.
我非常同意哈马尔的观点,但这里有一种方法可以做到这一点,有点:
这里是在行动:
理想情况下你会想要这样做:
但是该实例与成对的实例冲突。因此没有好方法为所有其他类型提供实例。
I very much agree with hammar, but here's a way to do it, sort of:
Here it is in action:
Ideally you'd want to do this:
But that instance conflicts with the one for pairs. So there's no good way to give an instance for every other type.
添加到哈马尔:我认为第二个示例就目前情况而言是不可能的,因为存在隐式类型转换。
为了讨论的目的,忽略这一点,类型签名会是什么样子:
所以,是的,这是可以想象的,但前提是可能需要指定返回类型。
Adding to hammar: I think the second example is not possible as it stands, because there are implicit type conversions.
Ignoring that for the sake of the discussion, how could the type signature look like:
So, yes, this is conceivable, yet with the provision that one may need to specify the return type.