如果我有一个递归ADT
data MyType = A | B | C MyType | D MyType MyType
Run Code Online (Sandbox Code Playgroud)
我可以编写一个函数来确定是否MyType包含A类似的实例:
hasA :: MyType -> Bool
hasA A = True
hasA B = False
hasA (C x) = hasA x
hasA (D x y) = (hasA x) || (hasA y)
Run Code Online (Sandbox Code Playgroud)
这适用于非循环实例,但它不会停止循环结构,例如
let x = C x in hasA x
Run Code Online (Sandbox Code Playgroud)
相反,在这个例子中它应该返回False.在其他情况下(利用D),它将错误地停止而不是返回True.
那么,问题是我如何最容易地编写类似于hasA循环结构的函数?Racket以这种形式有一个特别好的功能define/fix,它允许你创建一个像hasA预期的那样的行为,并返回False上面例子中的结构,几乎没有任何额外的代码.有没有办法在Haskell中做类似的事情?它有延伸吗?
编辑:我现在发现define/fix实际上是由Matt Might创建的一个宏 …
我目前正在探索设计一个可以在多个阶段转换AST的编译器.我们的想法是,从解析树开始,每次传递都会转换树,直到生成的AST得到优化,并包含生成中间代码所需的树的每个节点中的所有必需信息(在本例中为LLVM IR).树上的传递可能会显着改变其结构,例如通过运算符优先级解析将运算符和操作数列表更改为有序操作的层次结构.请注意,传递可能会使结构的某些部分完全不变.
所以,我的问题是我如何最好(阅读:最容易,尽可能少的重复)代表一个在C++中有多个中间表示的AST?我希望每个阶段的AST版本中的节点类型在编译时遵守它们的不兼容性.我认为关键问题是如何在避免重复代码的同时代表结构中不改变通道的部分?我想这是编译器作者过去多次解决的问题.
请注意,我目前在我的AST中使用Boost Variant而不是普通的运行时多态,并且希望解决方案与它兼容.
在类型系列的Haskell维基页面上,有以下示例列表:
type family F a :: *
type instance F [Int] = Int -- OK!
type instance F String = Char -- OK!
type instance F (F a) = a -- WRONG: type parameter mentions a type family
type instance F (forall a. (a, b)) = b -- WRONG: a forall type appears in a type parameter
type instance F Float = forall a.a -- WRONG: right-hand side may not be a forall type
type instance where -- …Run Code Online (Sandbox Code Playgroud) 我需要解决一个欠定的线性方程组和约束系统,然后找到最小化成本函数的特定解决方案.这需要在纯粹可移植的托管代码中完成,该代码将在.NET和Mono中运行.我可以使用哪些免费的库来实现它?
我发现免费库提供的所有优化算法都只支持单个变量的区间约束,例如0 < x < 1,不支持约束x + 2y < 4.我还发现通常线性方程求解器仅支持具有一个解的线性系统.
到目前为止我发现的最接近的是DotNumerics,其中包括用于求解欠定线性系统的奇异值分解,但其优化算法仅支持单变量约束(据我所知).
还有其他一些问题涉及线性规划,但我的关键要求是多变量约束和解决欠定系统.我还没有找到一个支持多变量约束的免费库.
我一直试图掌握Boost MPL.
作为简单的练习,我试过:
typedef vector_c<int, 1, 2, 3, 4, 5>::type example_list;
typedef transform<example_list, times<_, int_<2> > >::type doubled_example_list;
typedef transform<example_list, negate<_> >::type negated_example_list;
BOOST_STATIC_ASSERT((at_c<negated_example_list, 2>::type::value==-3));
BOOST_STATIC_ASSERT((at_c<doubled_example_list, 4>::type::value==10));
Run Code Online (Sandbox Code Playgroud)
一切都很好.但是,以下尝试无法编译:
typedef transform<_, negate<_> > negate_a_list;
typedef apply<negate_a_list, example_list>::type negated_example_list_2;
BOOST_STATIC_ASSERT((at_c<negated_example_list_2, 2>::type::value==-3));
Run Code Online (Sandbox Code Playgroud)
我认为这与占位符的范围有关negate_a_list,但我不知道如何解决它.有任何想法吗?我还怀疑我对MPL语法和语义的一些假设是有缺陷的.我会很感激任何关于缓和MPL的提示.
PS以下是上述代码的序言:
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/negate.hpp>
#include <boost/mpl/at.hpp>
using namespace boost::mpl;
using namespace boost::mpl::placeholders;
Run Code Online (Sandbox Code Playgroud) 这个问题出现在我正在编写的模块中,但我做了一个表现出相同行为的最小案例.
class Minimal[T](x : T) {
def doSomething = x
}
object Sugar {
type S[T] = { def doSomething : T }
def apply[T, X <: S[T]] (x: X) = x.doSomething
}
object Error {
val a = new Minimal(4)
Sugar(a) // error: inferred [Nothing, Minimal[Int]] does not fit the bounds of apply
Sugar[Int, Minimal[Int]](a) // works as expected
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器设法找出Minimal(Int)的内部参数,但然后设置Tto 的另一个匹配Nothing,显然不匹配apply.这些肯定是一样的T,因为删除第一个参数会使第二个参数抱怨T未定义.
是否有一些含糊不清意味着编译器无法推断出第一个参数,或者这是一个错误?我可以优雅地解决这个问题吗?
更多信息:此代码是尝试语法糖的简单示例.原始代码试图使|(a)|模数为均值a …
这个答案演示了一个多变量函数,它总结了它的参数:
class SumRes r where
sumOf :: Integer -> r
instance SumRes Integer where
sumOf = id
instance (Integral a, SumRes r) => SumRes (a -> r) where
sumOf x = sumOf . (x +) . toInteger
Run Code Online (Sandbox Code Playgroud)
我为以下所有成员创建了此函数的通用版本Num:
class (Num n) => MySumType n r where
mySum :: n -> r
instance (Num n) => MySumType n n where
mySum x = x
instance (Num n, MySumType n r) => MySumType n (n->r) where
mySum x = …Run Code Online (Sandbox Code Playgroud) 我有一个课程延伸android.os.Handler.该处理程序的一个实例被传递给a的构造函数Messenger.该Messenger的IBinder距离getBinder作为的结果,通过onBind我的服务事件.通过绑定程序从远程应用程序发送的消息确实转到处理程序的handleMessage方法,但是对内部Binder.getCallingUid和Binder.getCallingPid内部的调用handleMessage始终返回服务进程的uid和pid(这绝对不是与远程应用程序相同的进程).handleMessage绝对是IPC交易的一部分,不是吗?那么我哪里出错了?我需要这个来处理连接应用程序的身份验证.
提前致谢.
编辑
好.我有这种可怕的感觉,handleMessage它不是IPC事务的一部分,因为它发生在AIDL的单独线程中,它将消息放入队列中Messenger.有没有其他方法来获取呼叫者的用户ID和进程ID?
我有一个奇怪的重复模板模式类和派生类,如下所示:
template<class Derived>
class A {
typedef typename Derived::C D;
D x;
};
class B : public A<B> {
public:
class C { };
};
Run Code Online (Sandbox Code Playgroud)
由于在编译器尝试定义D时未完全定义B,因此无法编译.如何实现类似的结果,即具有B中定义的类型的A成员?或者我是否必须强制C在B之外定义?
我希望有一个宏,它使用它所使用的类的类型,而不将该名称传递给宏。为此我尝试过typedef decltype(*this) my_type;,但是this只能在非静态成员函数中使用。有任何想法吗?
编辑(评论副本):
我创建了一个基类和一组宏,可以使用 CRTP 无缝地实现类数据的三重缓冲。当一个三重缓冲类继承另一个三重缓冲类时,情况就变得复杂起来,实际上有两个基类 - 隐藏在宏中的 CRTP 基类和显式基类。由于显式基类也继承自 CRTP 基类的不同实例,因此派生类中的成员函数在两个基类之间会发生冲突。我正在编写一个宏,通过重新实现派生类中的函数来自动解决此冲突。此重新实现需要派生类的类型才能访问 CRTP 类的正确实例化,因此出现了最初的问题。
c++ ×4
haskell ×3
.net ×1
android ×1
boost-mpl ×1
c# ×1
crtp ×1
mono ×1
parse-tree ×1
polyvariadic ×1
scala ×1
templates ×1
type-bounds ×1