在Haskell的existentials上阅读本页后,我不得不测试这种行为的限制,所以我编写了以下代码片段:
{-# LANGUAGE ExistentialQuantification #-}
data Showable = forall a. Show a => MkShowable a
pack :: Show a => a -> Showable
pack = MkShowable
instance Show Showable where
show (MkShowable x) = show x
Run Code Online (Sandbox Code Playgroud)
该Showable类型ShowBox与上述链接中创建的类型非常相似.然后我创建了这个人为的例子来说明我的问题.
showSomething :: Bool -> Showable
showSomething True = pack 1
showSomething False = pack "ABC"
main :: IO ()
main = do
x <- getLine
let y = read x
print $ showSomething y
Run Code Online (Sandbox Code Playgroud)
这段代码(工作正常)要求用户输入(应为'True'或'False'),然后打印输出1是否为True或 …
我想从输入文件(可能已经或可能没有被用户修改)中读取字符串.我想将此字符串视为要使用固定数量的参数调用的格式指令.但是,据我所知,某些格式指令(特别是,~/脑海中浮现)可能会用于注入函数调用,这使得这种方法本质上不安全.
当read用于解析Common Lisp中的数据时,该语言提供了*read-eval*动态变量,可以将其设置nil为禁用#.代码注入.我正在寻找类似的东西,以防止代码注入和格式指令内的任意函数调用.
此代码基于boost::process1.65.1样本,并修复了一些拼写错误:
#include <boost/process.hpp>
int main(int argc, char *argv[])
{
boost::asio::io_service ios;
std::future<std::vector<char>> output, error;
boost::process::child c("hostname.exe",
boost::process::std_out > output,
boost::process::std_err > boost::process::null,
ios);
ios.run();
c.wait();
if (output.valid())
{
auto processOutput = output.get();
processOutput.push_back('\0');
printf(processOutput.data());
}
if (error.valid())
{
auto processError = error.get();
processError.push_back('\0');
printf(processError.data());
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作.它运行hostname.exe并打印其输出,即您的计算机网络名称.
您可能会看到该error变量未使用.阅读也是合乎逻辑的stderr,即使hostname.exe不经常使用它,现实的子过程当然也可以使用它.它看起来琐碎只需更换boost::process::std_err > boost::process::null用boost::process::std_err > error.但是,它会导致崩溃.错误消息如下:
vector iterator not dereferencable
Run Code Online (Sandbox Code Playgroud)
有谁知道原因以及如何绕过这个bug?
Rust 的迭代有两个主要特征:Iterator可以按顺序遍历的标准,以及DoubleEndedIterator可以从后面额外迭代的标准。
这对我来说很有意义。许多有用的方法都定义在Iterator、map、filter等上。然后,从“后面”操作的东西,可以说,像rfind和 一样rfold被定义,DoubleEndedIterator因为这样的操作只在这样的迭代器上才有意义。
但我们有Iterator::rev
Run Code Online (Sandbox Code Playgroud)fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator, { Rev::new(self) }
rev是一个定义的函数,但也有Iterator一个附加约束。SelfDoubleEndedIterator
定义此函数有什么实际好处Iterator?我们只能在DoubleEndedIterator实现者和DoubleEndedIterator扩展上调用它,Iterator因此我们永远不会遇到实现前者而不是后者的情况。那么为什么没有在like和arerev上定义呢?DoubleEndedIteratorrfindrfold
我想要做的是这样的:
(defgeneric fn (x))
(defmethod fn ((x (integer 1 *)))
"Positive integer")
(defmethod fn ((x (integer * -1)))
"Negative integer")
Run Code Online (Sandbox Code Playgroud)
我想一个通用的函数,任意类型说明符,包括基于列表的的,如工作(and x y),(or x y),(satisfies p),等.现在,当我试图运行上面的代码,我得到一个"无效的专用函数"的错误.一些研究表明,defgeneric它设计用于CLOS,而不是任意类型说明符.Common Lisp中是否存在类似defgeneric的系统,它会让我获得任意类型说明符所需的行为,而不仅仅是类?
我正在编写一个 Common Lisp 应用程序。我想要一个 Bash 脚本作为应用程序的入口点。目前,我已经编写了脚本,因此用户必须输入他们的 Common Lisp 实现的名称才能运行它,所以我会./script.sh clisp为 GNU CLISP编写代码,但使用 SBCL 的人必须编写./script.sh sbcl. 这是必要的,因为与 Python 和 Ruby 等语言不同,Common Lisp 实现没有任何标准名称或调用它们的标准化方法。
有什么技巧可以检测安装了哪个 Common Lisp 实现,也许是环境变量或其他什么?基本上,我正在寻找比强迫用户传递实现名称更好的方法。
在Scala中,有一种通常被称为"pimp my library"的设计模式.基本的想法是我们有一些类Foo(可能在某些库中我们无法修改),并且我们想要表现Foo得像它有一些方法或行为frobnicate,我们可以使用隐式类在事后添加方法.
implicit class Bar(val foo: Foo) extends AnyVal {
def frobnicate(): Unit = {
// Something really cool happens here ...
}
}
Run Code Online (Sandbox Code Playgroud)
然后,如果我们有一个实例Foo,我们可以调用frobnicate它,只要Bar在范围内,Scala编译器就足够聪明,可以隐式转换Foo为Bar.
val foo = new Foo()
foo.frobnicate() // Correctly calls new Bar(foo).frobnicate()
Run Code Online (Sandbox Code Playgroud)
我想在C++中做同样的事情.我知道C++有隐式转换,但在访问成员时它们似乎没有触发.举个具体的例子,C++中的以下代码会产生错误.
class Foo {}; // Assume we can't modify this class Foo
class Bar {
private:
Foo foo;
public:
Bar(Foo foo) : foo(foo) {}
void frobnicate() { …Run Code Online (Sandbox Code Playgroud) 假设我正在设计一种特定于领域的语言。对于这个简化的示例,我们有变量、数字以及将事物添加在一起的能力(变量或数字)
class Variable
attr_reader :name
def initialize(name)
@name = name
end
end
class Addition
attr_reader :lhs, :rhs
def initialize(lhs, rhs)
@lhs = lhs
@rhs = rhs
end
end
Run Code Online (Sandbox Code Playgroud)
现在,如果我想表示表达式x + 1,我会写Addition.new(Variable.new('x'), 1)。
我们可以通过+在 上提供一种方法来使这更方便Variable。
class Variable
def +(other)
Addition.new(self, other)
end
end
Run Code Online (Sandbox Code Playgroud)
然后我们就可以写了Variable.new('x') + 1。
但现在,假设我想要相反的结果:1 + x。显然,我不想进行猴子补丁Integer#+,因为这会永久禁用普通的 Ruby 整数加法。我认为这将是一个很好的改进用例。
具体来说,我想定义一个方法expr,该方法采用一个块并在重新定义的上下文中评估该块+以构造我的 DSL 实例。也就是说,我想要类似的东西
module Context
refine Integer do
def +(other)
Addition.new(self, other) …Run Code Online (Sandbox Code Playgroud) 几乎所有使用 IEEE 浮点值的人都曾在某些时候遇到过 NaN(即“不是数字”)。众所周知,NaN 不等于其自身。
>>> x = float('nan')
>>> x == x
False
Run Code Online (Sandbox Code Playgroud)
现在,我已经接受了这一点,但我却很难理解一种奇怪的行为。即,
>>> x in [x]
True
Run Code Online (Sandbox Code Playgroud)
我一直以为是list.__contains__这样写的
def __contains__(self, element):
for x in self:
if element == x:
return True
return False
Run Code Online (Sandbox Code Playgroud)
即,它__eq__在内部使用相关数据类型。确实如此。__eq__如果我使用自己设计的方法定义自定义类,那么我可以验证 Python__eq__在执行包含检查时确实进行了调用。但是,怎么可能存在一个x既为x == x假又为x in [x]真的值(在我们的例子中为 NaN)呢?
__eq__我们也可以通过习俗观察到相同的行为。
class Example:
def __eq__(self, other):
return False
x = Example()
print(x == x) # False
print(x in [x]) # …Run Code Online (Sandbox Code Playgroud) 我正在玩Haskell中的存在感和GADT,我正在尝试为组合器定义DSL(例如SKI).我有GADT工作,以及一个工作正常的减少功能(并且与问题无关)
{-# LANGUAGE GADTs, ExistentialQuantification #-}
import Control.Applicative
import Data.Monoid
import Control.Monad
data Comb t where
S :: Comb ((a -> b -> c) -> (a -> b) -> a -> c)
K :: Comb (a -> b -> a)
I :: Comb (a -> a)
B :: Comb ((b -> c) -> (a -> b) -> a -> c)
C :: Comb ((b -> a -> c) -> a -> b -> c)
W :: Comb ((a -> a …Run Code Online (Sandbox Code Playgroud) common-lisp ×3
c++ ×2
haskell ×2
types ×2
bash ×1
boost ×1
combinators ×1
detection ×1
dsl ×1
equality ×1
gadt ×1
iterator ×1
lisp ×1
nan ×1
polymorphism ×1
python ×1
refinements ×1
ruby ×1
rust ×1
sanitization ×1
scala ×1
windows ×1