来自C++,我发现通用编程是不可或缺的.我想知道人们如何在Haskell中接近它?
说如何在Haskell中编写通用交换函数?
在Haskell中是否存在部分特化的等价概念?
在C++中,我可以部分地使用特殊的泛型交换函数来处理泛型map/hash_map容器,该容器具有O(1)容器交换的特殊交换方法.你如何在Haskell中做到这一点,或者Haskell中泛型编程的典型例子是什么?
我正在编写处理来自Language.Exts.Annotated.Syntax的值的代码,其中定义了各种类型的镜像Haskell模块的结构:
data Module l = ...
data Decl l = ...
data Exp t = ...
-- etc
Run Code Online (Sandbox Code Playgroud)
我希望能够编写处理这些数据结构并对它们执行各种转换的函数.因为没有一种常见的数据类型,所以我无法编写一个可以完成所有操作的函数.
到目前为止,我已经编写了一个Tree包装这些类型的类型,以便我的转换函数可以执行Tree l -> Tree l:
data Tree l = ModuleT (Module l)
| DeclT (Decl l)
| ExpT (Exp l)
-- etc copy & paste
Run Code Online (Sandbox Code Playgroud)
但是我现在发现自己编写了很多代码,需要Module包含它ModuleT,包装它,调用函数,然后再将结果重新打包Module.我有:
class AnnotatedTree ast where
tree :: ast l -> Tree l
untree :: Tree l -> ast l
instance AnnotatedTree Module where
tree …Run Code Online (Sandbox Code Playgroud) 有没有办法可以避免类型擦除并获得类型参数的访问权限?
public class Foo<T extends Enum<?> & Bar> {
public Foo() {
// access the template class here?
// i.e. :
baz(T.class); // obviously doesn't work
}
private void baz(Class<T> qux) {
// do stuff like
T[] constants = qux.getEnumConstants();
...
}
}
Run Code Online (Sandbox Code Playgroud)
我需要知道T并用它做事.是否可能,如果是这样,如果不在构造函数中传递类或参数之外的任何地方,如何才能完成?
编辑:这个问题的主要目的是找出是否有任何关于类型擦除的实用方法.
在C++中,您可以使用模板同时拥有通用容器和类型安全容器.但是在C中,如果你想要通用容器,你必须(afaik)使用void*,这意味着你失去了类型安全性.要拥有类型安全的容器,您必须为要保留的每种类型的数据重新实现它们.
鉴于C遵循比C++ 更多的程序员知道他所做的理念,在C中做什么更惯用的事情:使用通用容器void*,或为每种类型的数据制作自定义容器?
我必须经常在Scala中转换"矩形"集合集合,例如:地图列表,列表地图,地图地图,一组列表,集合地图等.因为集合可以统一被视为从特定域到共域的映射(例如:List [A]/Array [A]是从Int域到A域的映射,Set [A]是来自A的映射域到布尔共域等),我想编写一个干净的通用函数来进行转置操作(例如:将列表映射转换为转置的映射列表).但是,我遇到了麻烦,因为除了()运算符之外,Scala似乎没有统一的API来抽象地查看集合作为映射?
所以我最终为每种类型的集合集合编写了一个单独的转置,如下所示:
def transposeMapOfLists[A,B]( mapOfLists: Map[A,List[B]] ) : List[Map[A,B]] = {
val k = ( mapOfLists keys ) toList
val l = ( k map { mapOfLists(_) } ) transpose;
l map { v => ( k zip v ) toMap }
}
def transposeListOfMaps[A,B]( listOfMaps: List[Map[A,B]]) : Map[A,List[B]] = {
val k = ( listOfMaps(0) keys ) toList
val l = ( listOfMaps map { m => k map { m(_) } } ) transpose;
( …Run Code Online (Sandbox Code Playgroud) collections transpose functional-programming scala generic-programming
我在下面的方法中写了以下要求 -
如果传递的attributeName中没有值,则应返回 -
3.1.对于int -1 3.2.对于Datetime DateTime.MinValue 3.3.对于String,null 3.4.对于bool,null
情况3.4下面的方法失败.
public T AttributeValue<T>(XmlNode node, string attributeName)
{
var value = new object();
if (node.Attributes[attributeName] != null && !string.IsNullOrEmpty(node.Attributes[attributeName].Value))
{
value = node.Attributes[attributeName].Value;
}
else
{
if (typeof(T) == typeof(int))
value = -1;
else if (typeof(T) == typeof(DateTime))
value = DateTime.MinValue;
else if (typeof(T) == typeof(string))
value = null;
else if (typeof(T) == typeof(bool))
value = null;
}
return (T)Convert.ChangeType(value, typeof(T));
}
Run Code Online (Sandbox Code Playgroud)
当改变这个
public System.Nullable<T> AttributeValue<T>(XmlNode node, string …Run Code Online (Sandbox Code Playgroud) 假设您有类似以下的案例类
case class Test1(a:String,b:Int,c:Char)
case class Test2(a:String,b:Int)
Run Code Online (Sandbox Code Playgroud)
并使用以下变量实例化类
val test1 = Test1("first",2,'3')
val test2 = Test2("1st",20)
Run Code Online (Sandbox Code Playgroud)
有没有办法使用该.copy方法(或其他方法),将Test2中的变量应用于Test1,如
val test3 = test1.copy(test2) //Note this isn't valid scala code
// Result should be ("1st",20,'3')
Run Code Online (Sandbox Code Playgroud)
如果在纯scala中这是不可能的,那么它将如何在Shapeless 1/2中完成(当前代码在Shapeless 1中,但我们计划在某个时间点升级到Shapeless 2)
我很好奇是否可以编写一个函数apply_nth,它接受一个函数,一个参数的数量,以及该参数的值,然后返回一个新的,部分应用的函数.
我得到的感觉是,由于类型系统这是不可能的,但我无法得出令人满意的答案.我也无法想出一个工作型签名.
如果语言更松散,我想代码可能看起来像这样.
apply_nth f 0 x = f x
apply_nth f n x = \a -> apply_nth (f a) (n-1) x
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
haskell functional-programming generic-programming dependent-type
我最近添加了一个alterF函数Data.Map,这是一个翻转形式Control.Lens.At.at.
alterF :: (Ord k, Functor f)
=> (Maybe a -> f (Maybe a))
-> k
-> Map k a
-> f (Map k a)
Run Code Online (Sandbox Code Playgroud)
alterF被设计为能够提供合理的性能,即使对于非常"沉重"的仿函数[],甚至当密钥相当昂贵时也是如此.不幸的是,它比一个轻量级算子和便宜比较键的更常见情况下的速度慢一些.
为了解决这个问题,我为这些Const b和Identity仿函数添加了GHC重写规则,将它们重写为通常更快的更简单的实现.我准备添加另一个,因为.我添加了一个(,) b(,) b然后将其删除.请参阅下面的更新.
但是,我对我需要一个特定规则的事实感到有些恼火(,) b,因为还有许多其他仿函数遵循相同的模式.特别是,任何时候定义仿函数
data F b1 b2 ... a = F e1 ... a ... e_n
Run Code Online (Sandbox Code Playgroud)
在没有e_k提及的地方a,我应该能够以同样的方式重写它.有没有办法用GHC做到这一点RULES?或者我将不得不等待更一般的重写系统?
可悲的是,我意识到我对对的重写规则是无效的(它太严格了),并且修复使得它不那么明显有益.所以我现在已经取消了这条规则.不过,我认为一般性问题仍然很有意思.
我想编写泛型函数(例如,获取'void**'类型的数组并对此数组做一些事情的函数),这样这个函数将得到元素的类型(在示例中,它将是类型数组中的任何元素)作为参数.
我可以用c做吗?
例如:
我想编写一个获取数组(类型为void**)的函数,并以某种随机方式初始化此数组.
什么是"以某种随机方式"的含义 - 例如作为参数获取的函数:array(在类型void**中),数组中任何元素的类型,index(在int的类型中)并初始化此单元格.
haskell ×4
c ×2
scala ×2
c# ×1
case-class ×1
collections ×1
containers ×1
generics ×1
ghc ×1
idioms ×1
java ×1
nullable ×1
shapeless ×1
templates ×1
transpose ×1
type-erasure ×1
types ×1