我知道当我读到这个答案时,我会发现我忽略了一些在我眼前的东西.但我花了最后30分钟试图弄清楚自己没有结果.
所以,我在Java 6中编写了一个程序,并发现了一些(对我来说)奇怪的功能.为了尝试隔离它,我做了两个小例子.我首先尝试了以下方法:
private static int foo()
{
return null;
}
Run Code Online (Sandbox Code Playgroud)
并且编译器拒绝它:类型不匹配:无法从null转换为int.
这对我很好,它尊重我熟悉的Java语义.然后我尝试了以下内容:
private static Integer foo(int x)
{
if (x < 0)
{
return null;
}
else
{
return new Integer(x);
}
}
private static int bar(int x)
{
Integer y = foo(x);
return y == null ? null : y.intValue();
}
private static void runTest()
{
for (int index = 2; index > -2; index--)
{
System.out.println("bar(" + index + ") = " + bar(index));
}
}
Run Code Online (Sandbox Code Playgroud)
编译没有错误!但是,在我看来,行中应该存在类型转换错误 …
我对Haskell相对较新,我正在尝试学习如何使用do符号按顺序执行不同的操作.特别是,我正在编写一个程序来对算法进行基准测试(一个函数)
foo :: [String] -> [String]
Run Code Online (Sandbox Code Playgroud)
为此,我想写一个像这样的函数
import System.CPUTime
benchmark :: [String] -> IO Integer
benchmark inputList = do
start <- getCPUTime
let r = foo inputList
end <- getCPUTime
return (end - start) -- Possible conversion needed.
Run Code Online (Sandbox Code Playgroud)
最后一行可能需要转换(例如,毫秒),但这不是这个问题的主题.
这是衡量在某个参数inputList上计算函数foo所需时间的正确方法吗?
换句话说,foo inputList
在end <- getCPUTime
执行操作之前,表达式是否会完全减少?或者r
只会被束缚foo inputList
?
更一般地说,如何在执行某些操作之前确保完全评估表达式?
这个问题几个月前被问到程序员(见这里)并在那里得到了一个可接受的答案,但它已被关闭为主题,因为它属于堆栈溢出.问题无法移动到堆栈溢出,因为它超过60天.因此,与主持人达成一致意见,我在此处重新提出问题并自行发布已接受的问题,因为我认为它包含一些有用的信息.
我一直在constexpr
研究C++ 的新功能,但我并不完全理解它的必要性.
例如,以下代码:
constexpr int MaxSize()
{
...
return ...;
}
void foo()
{
int vec[MaxSize()];
}
Run Code Online (Sandbox Code Playgroud)
可以替换为:
int MaxSize()
{
...
return ...;
}
static const int s_maxSize = MaxSize();
foo()
{
int vec[s_maxSize];
}
Run Code Online (Sandbox Code Playgroud)
更新
第二个例子实际上不是标准的ISO C++(感谢几个用户指出这一点),但某些编译器(例如gcc)支持它.因此,这不是const
使程序有效,而是gcc支持这种非标准功能的事实.(据我所知,只有当数组被定义为函数或方法的本地数据时才有可能,因为在编译时必须知道全局数组的大小.)如果我编译没有选项-std=c++98 -pedantic-errors
,甚至代码
int MaxSize()
{
return 10;
}
void foo()
{
int vec[MaxSize()];
}
Run Code Online (Sandbox Code Playgroud)
将使用gcc编译.
因此,考虑到目前为止的反馈(以及我在同一时间进行的一些进一步阅读),我将尝试重新解释我的问题.
我const
大量使用关键字.随着const
我可以定义有其整个生命周期内某一特定值的常数.可以使用任何表达式初始化常量,该表达式被计算一次,即创建常量时.对于这些情况,我认为这constexpr
是非常无用的:它将引入一个非常小的优化,因为定义常量值的表达式将在编译时而不是运行时计算.每次我需要一个复杂初始化的运行时常量时我都会使用关键字const
.
因此constexpr
,在我们需要在编译时初始化常量的情况下,可能会派上用场.一个示例是矢量定义:标准不支持在运行时定义大小.另一个示例是具有一个或多个非类型参数的模板.
在这种情况下,我通常使用宏:
#define MAX_SIZE (10)
void foo()
{
int …
Run Code Online (Sandbox Code Playgroud) 在这个问题中,OP询问表达式的类型是什么,return 5
并且在该问题中已经给出了答案:它是泛型类型,可以通过键入来验证
:t return 5
Run Code Online (Sandbox Code Playgroud)
在Haskell解释器中:
return 5 :: (Num a, Monad m) => m a
Run Code Online (Sandbox Code Playgroud)
的具体实现return
是通过在它出现的上下文确定:类型推断将限制m
到特定的单子如Maybe
,[]
,IO
,等.
我也可以强制解释器通过指定类型来选择特定的monad,例如
Prelude> return 5 :: Maybe Int
Just 5
Prelude> return 5 :: [Int]
[5]
Run Code Online (Sandbox Code Playgroud)
等等.
现在如果我在return 5
没有指定类型的情况下键入表达式,我得到:
Prelude> return 5
5
Run Code Online (Sandbox Code Playgroud)
这对我来说是非常令人惊讶的:我宁愿期望解释器告诉我它不能选择合适的实现,return
因为它无法推断出要使用的monadic类型.
所以我的问题是:Haskell在这里使用了哪些具体的monad?根据这个monad选择的标准?
编辑
谢谢你的回答!事实上,如果我尝试编译这个程序:
module Main
where
a = return 5
main :: IO ()
main = putStrLn "This program should not compile" …
Run Code Online (Sandbox Code Playgroud) 我在Haskell中实现了一个过滤器,即我可以从命令行调用的程序,如下所示:
$ cat inputfile.txt | myFilter > outputfile.txt
Run Code Online (Sandbox Code Playgroud)
在大约80 MB的文件上运行程序时,我得到堆栈溢出(堆栈空间溢出:当前大小8388608字节.).我在cygwin下使用GHC版本6.12.3.
我认为这个问题来自于sort
我在程序中使用的功能,但在我一直在寻找问题三天之后,我不知道如何解决这个问题,所以我想如果有人能给我一个提示.
以下是有关我的计划的重要细节.
我的过滤程序将标准输入读入字符串,将其拆分为行并将每行解析为某种类型的记录 Event
data Event = ...
Run Code Online (Sandbox Code Playgroud)
这是一个实例 Ord
instance Ord Event where
x < y = ...
Run Code Online (Sandbox Code Playgroud)
这样我就可以使用内置sort
函数对事件进行排序.
分割成行并解析事件(每行一个事件)由函数执行
p :: String -> [Event]
Run Code Online (Sandbox Code Playgroud)
内部使用标准功能lines
.
我还有一个功能g分组事件:
g :: [Event] -> [[Event]]
Run Code Online (Sandbox Code Playgroud)
g使用了一些与此无关的标准; 每组最多可包含4个事件.
我使用sort
(即,每个组内的所有事件进行排序)对每组事件(表示为列表)进行排序,最后使用函数将所有事件组格式化为字符串
f :: [[Event]] -> String
Run Code Online (Sandbox Code Playgroud)
主要功能如下:
main = interact (f . (map sort) . g . p)
Run Code Online (Sandbox Code Playgroud)
如上所述,在大约80 MB的文件上运行此程序会导致堆栈溢出.
如果我用以下函数替换sort函数(一个简单的快速排序实现):
mySort :: [Event] -> [Event]
mySort …
Run Code Online (Sandbox Code Playgroud) 我正在将一个Java应用程序移植到Haskell.Java应用程序的主要方法遵循以下模式:
public static void main(String [] args)
{
if (args.length == 0)
{
System.out.println("Invalid number of arguments.");
System.exit(1);
}
SomeDataType d = getData(arg[0]);
if (!dataOk(d))
{
System.out.println("Could not read input data.");
System.exit(1);
}
SomeDataType r = processData(d);
if (!resultOk(r))
{
System.out.println("Processing failed.");
System.exit(1);
}
...
}
Run Code Online (Sandbox Code Playgroud)
所以我有不同的步骤,每个步骤后我都可以退出错误代码,或继续执行以下步骤.
我将此移植到Haskell的尝试如下:
main :: IO ()
main = do
a <- getArgs
if (null args)
then do
putStrLn "Invalid number of arguments."
exitWith (ExitFailure 1)
else do
-- The rest of the main function …
Run Code Online (Sandbox Code Playgroud) 我一直在查看Scala文档,但到目前为止我没有找到我的问题的答案,即该方法使用了什么排序算法
scala.collection.immutable.Vector.sorted
Run Code Online (Sandbox Code Playgroud)
该文档说它是一种稳定的排序,但不是实际使用的算法.它是合并排序吗?
我正在使用Racket和DrRacket进行一个小项目(我正在尝试学习它们并使用它们来教我的朋友一些函数式编程).
我刚刚发现了自动完成功能(C- /),它可以很好地处理库函数,但它不会看到我自己的函数.
我还补充说
(provide (all-defined-out))
Run Code Online (Sandbox Code Playgroud)
在我的源文件的开头(我认为自动完成功能可能看不到符号,因为它们不会被导出)但这并不能解决问题.
所有符号都可以在DrRacket REPL中访问(我可以评估我的功能,它们工作正常).
你能告诉我如何解决这个问题吗?我需要配置什么吗?
我已经安装了typesafe激活器,创建了一个项目,添加了我自己的Scala类并成功编译并运行了我的代码.
现在我正在寻找一个函数来使用激活器来遮蔽我的项目(类似于玩游戏可以做的事情),但我既没有在类型安全网站上找到任何东西,也没有通过搜索互联网找到任何东西.
激活剂是否提供这样的功能?
Java在开发过程中是否始终保持源代码向后兼容性?
更确切地说:给定两个Java版本X和Y,其中X <Y,Java X的任何程序也是Java Y的有效程序,具有相同的语义?例如,X = Java 2(或旧的编号为1.2),Y = Java 5.
或者只有JVM级别的兼容性:例如,JVM 5可以运行为JVM 1.2编译的类吗?
如果可以在Java 5(或6或7)上运行Java 2代码,那么我必须遵循的具体步骤是什么?直接使用Java 5编译器编译?使用Java 2编译器编译并在JVM 5上运行?