我遇到了一个奇怪的错误,我认为这是一个错误.这是一个小例,请不要评论代码的用处:)
class Foo {
static public <X> int bar() { return 42; }
public int baz() {
return true ? 42 : (
Foo.<Void>bar() > 42 ? 41 : 43
)
;
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
err.java:7: illegal start of expression
Foo.<Void>bar() > 42 ? 41 : 43
^
Run Code Online (Sandbox Code Playgroud)
我试过SUN SDK javac 1.6.0_13和1.6.0_21.
当我要么,错误消失了
所以看起来如果e是一个表达式,那么写(e)并不总是有效的?
我最近受到了Haskell博客活动1的启发,试图在Haskell中编写类似Forth的DSL.我采取的方法既简单又令人困惑:
{-# LANGUAGE TypeOperators, RankNTypes, ImpredicativeTypes #-}
-- a :~> b represents a "stack transformation"
-- from stack type "a" to stack type "b"
-- a :> b represents a "stack" where the top element is of type "b"
-- and the "rest" of the stack has type "a"
type s :~> s' = forall r. s -> (s' -> r) -> r
data a :> b = a :> b deriving Show
infixl 4 :>
Run Code Online (Sandbox Code Playgroud)
对于做简单的事情,这非常有效:
start …Run Code Online (Sandbox Code Playgroud) polymorphism haskell concatenative-language higher-order-functions impredicativetypes
我需要编写一个函数,它接受一个字符串列表并找到列表中最大的字符串.问题是它需要使用List.foldl迭代列表,并且不能使用递归调用,除了List,foldl的库函数中的那些调用.
我写
fun longest_string1(xs)=
case xs of
[] => ""
| x::xs' => List.foldl((fn (s,x) => if String.size s > String.size x then s else x) "" x,)
Run Code Online (Sandbox Code Playgroud)
我的解释如下:
-s in xs,如果xs为空则返回一个空字符串 -
另外xs调用的第一项List.foldl
-List.foldl传入一个匿名函数来检查s的长度,这应该是表示针对列表的head项的累加器.
- 将初始累加器设置为空字符串,将初始比较值设置为高阶函数传入的初始列表的头部
但是,它不进行类型检查.
我认为我的问题在于理解List.foldl函数本身以及它如何读取其参数.有人可以提供一些澄清吗?
我正在编写一个方法来打印它传递的每个Object.通过调用Object.toString()对象的方法可以正常工作,但不适用于数组.我可以通过该Object.getClass().isArray()方法找出它是否是一个数组,但我不知道如何投射它.
int[] a;
Integer[] b;
Object aObject = a;
Object bObject = b;
// this wouldn't work
System.out.println(Arrays.toString(aObject));
System.out.println(Arrays.toString(bObject));
Run Code Online (Sandbox Code Playgroud) 似乎Frege关于类型类的想法与Haskell有很大不同.特别是:
语法似乎不同,没有明显的原因.
函数类型不能包含类实例.(似乎是一个相当奇怪的规则......)
语言规范说明了在子类实例声明中实现超类.(但如果你有钻石继承,那就不行了......这不会是一个错误,但它不能保证以某种方式工作?)
弗雷格对实例的看法不那么挑剔.(允许输入别名,类型变量不需要是不同的,等等)
方法可以声明为native,虽然还不完全清楚这是什么意思.
您似乎可以编写type.method访问方法.同样,没有迹象表明这意味着什么或为什么它有用.
子类声明可以为超类方法提供默认实现.(?)
简而言之,如果知道这些东西的人可以写出这些东西如何工作的解释将是有用的.它在语言规范中列出,但描述有点简洁.
(关于语法:我认为Haskell的实例语法更合乎逻辑."如果X是Y和Z的实例,那么它也是以下列方式的Q实例......"Haskell的类语法总是看起来有点奇怪对我来说.如果X实现Eq,这并不意味着它实现Ord,它暗示它可以实现,Ord如果它想要.我不知道什么是更好的符号将...)
Per Ingo的回答:
例如,假设Foo是一个超类Bar.假设每类有三种方法(foo1,foo2,foo3,bar1,bar2,bar3),并Bar提供了一个默认的实现foo1.这应该意味着
instance Bar FB where foo2 = ... foo3 = ... bar1 = ... bar2 = ... bar3 = ...
应该管用.但是这会有用吗:
instance Foo FB where foo2 = ... foo3 = ... instance Bar …
问题告诉了一切.
对于专家来说,SUN java 5编译器是否有理由接受递归注释(与langspec相反),而后来的编译器却没有?我的意思是,什么可能是反对递归注释的论据.
编辑:递归注释类似于:
@Panel(layout=BorderLayout.class,
nested={
@Panel(region=NORTH, layout=FlowLayout.class, ...)
@Panel(region=SOUTH, layout=FlowLayout.class, ...)
}
)
Run Code Online (Sandbox Code Playgroud) 我认为,以下不能用Java完成.但我很乐意学习如何实现类似于它的东西.
假设我们有一个C类,它已经在编译代码中使用了.(我们既不能改变代码也不能改变C的原始定义).
进一步假设有一些有趣的代码可以重复使用,如果只有C实现接口I.事实上,导出D只是C +接口方法的实现,或多或少是微不足道的.
然而,一旦我有一个C,似乎没有办法说:我希望你成为一个D,也就是说,一个C实现我.
(旁注:我认为如果D是C,那么应该允许c的运行时类型为C的强制转换(D)c,并且C的唯一区别是添加方法.这应该是安全的,如果不是吗?)
怎么能解决这场灾难呢?
(我知道工厂设计模式,但这似乎不是一个解决方案.因为,一旦我们设法在以前是C的所有地方创建D,其他人发现另一个接口J有用并导出E扩展C实现J.但是E和D是不兼容的,因为它们都为C添加了一组不同的方法.因此,虽然我们总是可以传递一个预期C的E,但是我们不能通过一个预期D的E.而是,现在,我们需要一个新类F扩展C实现I,J.)
我写了一个很好的插件,它包含了一些生成的java源代码.
我可以很好地建立项目.我可以在运行配置中运行它,启动另一个eclipse,它可以根据自己的喜好运行.
所以我想:时间让它可以安装.
因此,我创建了一个功能项目和一个更新站点项目,并构建和导出它,看起来它工作正常.我甚至可以从我的更新站点"安装"它,或直接在正在运行的工作台中导出插件.我看到它已安装但如果我尝试打开一个会激活我的插件的文件,它会抛出异常.具体来说,它告诉我有"未解决的编译问题".
经过长时间的搜索,重建(没有错误),一次又一次地重新测试我找到一个logs.zip文件,其目录的名称类似于我的插件,其中有54k文件(请注意,它是2011年,磁盘空间非常稀缺,显然)有趣的名字@dot.log.看这样的文件一定是多么绝望?!但是,令人惊讶的是,它出现了54k错误消息,如下所示:
# 02.12.11 19:58:55 MEZ
# Eclipse Compiler for Java(TM) 0.B76_R37x, 3.7.1, Copyright IBM Corp 2000, 2011. All rights reserved.
----------
1. ERROR in X:\dev\frege\FregIDE\src\frege\IO.java (at line 1451)
final public static Consts ij = new Consts();
^
Syntax error on token "Invalid Character", delete this token
Run Code Online (Sandbox Code Playgroud)
当然,"无效字符"是完全合法的java标识符字符,只是它们不是ASCII字母.这就是为什么我设置为UTF-8的所有文件,都设置UTF-8作为默认编码,以及在此之前表示,与普通身材它完美的作品.
当我导出更新站点,功能或插件时,有没有办法阻止eclipse重新编译所有内容.这是我最喜欢的,因为一切都已编译,重新编译需要一分钟左右.(甚至还有一个标志"使用在工作区中编译的类文件."但它似乎什么都不做 - 它只是重新编译.)
替代方案:我可以以某种方式修改它用于构建它的脚本吗?我找不到他用来构建的蚂蚁脚本.如果我可以查找javac步骤并将编码UTF-8放在那里(这就是我期望的问题.)有一个"另存为Ant脚本"复选框,但Ant文件只包含:
<?xml version="1.0" encoding="UTF-8"?>
<project default="feature_export" name="build">
<target name="feature_export">
<pde.exportFeatures destination="x:\dev\frege\FregeUpdateSite"
exportSource="false" exportType="directory"
features="FregeFeature" useJARFormat="true"/>
</target>
</project>
Run Code Online (Sandbox Code Playgroud)
如果我不能阻止它编译,我如何让eclipse使用编译版本的正确设置?
我想知道是否有更深层次的原因我们不能抽象出类型类(或者我们可以吗?).
例如,当我们有
fzip :: (forall a.[a] -> [a]) -> [b] -> [c] -> [(b,c)]
fzip f xs ys = zip (f xs) (f ys)
Run Code Online (Sandbox Code Playgroud)
那我们可以说
fzip (drop 42) [1..100] ['a'..'z']
fzip reverse [1..100] ['a'..'z']
Run Code Online (Sandbox Code Playgroud)
等等.但我们做不到
fzip (map succ) [1..100] ['a'..'z']
Run Code Online (Sandbox Code Playgroud)
我们可以修复:
ezip :: (Enum b, Enum c) => (forall a.Enum a => [a] -> [a]) -> [b] -> [c] -> [(b,c)]
ezip f xs ys = zip (f xs) (f ys)
Run Code Online (Sandbox Code Playgroud)
同样我们可以解决
fzip (map (5*)) [1..100] [1.5, 2.3, 4.7]
Run Code Online (Sandbox Code Playgroud)
同 …
这是一个GHCi会议:
Prelude> words " one two three"
["one","two","three"]
Prelude> lines "\none\ntwo\nthree"
["","one","two","three"]
Run Code Online (Sandbox Code Playgroud)
有这种不一致的原因吗?如果是这样,它是什么?