我正在努力完成部分工作 http://ropas.snu.ac.kr/~bruno/papers/FOPOA.pdf
使用对象代数进行面向特征的编程
我不是scala程序员,我可以做一些F#和Haskell,但scala的细微差别对我来说并不明显......所以我尝试从文件中输入代码;
def fix[A](f: Open[A, A]): A = {
lazy val s: A = f(s); s
}
trait GExpAlg[In,Out] {
def Lit(x : Int) : Out
def Add(e1 : In, e2 : In) : Out
}
type ExpAlg[E] = GExpAlg[E,E]
type OExpAlg[S <: E, E] = GExpAlg[S, Open[S,E]]
type Open[S <: E, E] = (=> S) => E
trait IEval { def eval() : Int }
trait IPrint { def print() : String }
trait ExpPrint2[S <: IEval with IPrint] extends OExpAlg[S, IPrint] {
def Lit(x : Int) = self => new IPrint() { def print() = x.toString() }
def Add(e1 : S, e2 : S) = self => new IPrint() {
def print() = e1.print() + " + " + e2.print() + " = " + self.eval()
}
}
trait CloseAlg[E] extends ExpAlg[E] { val alg : OExpAlg[E,E]
def Lit(x : Int) : E = fix(alg.Lit(x))
def Add(e1 : E, e2 : E) : E = fix(alg.Add(e1,e2))
}
def closeAlg[E](a : OExpAlg[E,E]) : ExpAlg[E] = new CloseAlg[E] {
val alg = a
}
trait SelfAlg[Self <: Exp, Exp] {
val fself : ExpAlg[Self]
}
trait SelfExpAlg[Self <: Exp, Exp] extends GExpAlg[Self,Open[Self,Exp]] with SelfAlg[Self,Exp]
trait ExpPrint3[S <: IEval with IPrint] extends SelfExpAlg[S,IPrint]{
def Lit(x : Int) = self => new IPrint() {def print() = x.toString()}
def Add(e1 : S, e2 : S) = self => new IPrint() {
def print() = {
val plus54 = fself.Add(fself.Lit(5), fself.Lit(4));
e1.print() + " + " + e2.print() + " = " + self.eval() + " and " + "5 + 4 = " + plus54.eval();
}
}
}
def ExpPrint3[S <: IEval with IPrint] : OpenExpAlg[S,IPrint] = s => new ExpPrint3[S] {
lazy val fself = s
}
type OpenExpAlg[S <: E, E] = (=> ExpAlg[S]) => GExpAlg[S, Open[S,E]]
// this is where the error is....
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(compose(closeAlg,f))
错误:(154,55)未找到:值撰写 def close [S](f:OpenExpAlg [S,S]):ExpAlg [S] = fix(compose(closeAlg,f))
错误:(154,63)缺少对象ScalaApp中方法closeAlg的参数列表
未应用的方法仅在预期函数类型时转换为函数。
您可以通过撰写closeAlg _
或closeAlg(_)
代替closeAlg
来明确转换此内容。
我可以强制第二个错误消失,但我对无法找到合成感到困惑....(函数类型有些奇怪,它们是“按名称”,我不是太确定这意味着什么,也许就是那个)
我真的不知道我在scala中做了什么,我不知道IDE是如何工作的。 def close [S](f:OpenExpAlg [S,S]):ExpAlg [S] = fix(compose(closeAlg,f))
修改
由于以下答案,我修改了代码 下面是Cyrille Corpet
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(f.compose(closeAlg _))
我现在得到了;
Error:(160, 65) polymorphic expression cannot be instantiated to expected type;
found : [E]ScalaApp.OExpAlg[E,E] => ScalaApp.ExpAlg[E]
(which expands to) [E]ScalaApp.GExpAlg[E,(=> E) => E] => ScalaApp.GExpAlg[E,E]
required: ? => => ScalaApp.ExpAlg[S]
(which expands to) ? => => ScalaApp.GExpAlg[S,S]
def close[S](f : OpenExpAlg[S,S]) : ExpAlg[S] = fix(f.compose(closeAlg _))
答案 0 :(得分:1)
你应该对scala真正了解的是,一切都是一个对象。
特别是,函数是具有名为Count_group
的方法的对象,可以在不命名的情况下调用它,所以
ID Day Count Count_group
18 1933 6 15
33 1933 6 15
37 1933 6 15
18 1933 6 15
16 1933 6 15
11 1933 6 15
111 1932 5 15
34 1932 5 15
60 1932 5 15
88 1932 5 15
18 1932 5 15
33 1931 3 15
13 1931 3 15
56 1931 3 15
23 1930 1 15
111 1932 5 9
34 1932 5 9
60 1932 5 9
88 1932 5 9
18 1932 5 9
33 1931 3 9
13 1931 3 9
56 1931 3 9
23 1930 1 9
33 1931 3 4
13 1931 3 4
56 1931 3 4
23 1930 1 4
23 1930 1 1
6 1800 6 12
37 1800 6 12
98 1800 6 12
52 1800 6 12
18 1800 6 12
76 1800 6 12
55 1799 4 12
6 1799 4 12
52 1799 4 12
133 1799 4 12
112 1798 2 12
677 1798 2 12
55 1799 4 6
6 1799 4 6
52 1799 4 6
133 1799 4 6
112 1798 2 6
677 1798 2 6
112 1798 2 2
677 1798 2 2
778 888 4 8
111 888 4 8
88 888 4 8
10 888 4 8
37 887 2 8
26 887 2 8
8 886 1 8
56 885 1 8
37 887 2 4
26 887 2 4
8 886 1 4
56 885 1 4
8 886 1 2
56 885 1 2
56 885 1 1
22 120 2 6
34 120 2 6
88 119 1 6
99 118 2 6
12 118 2 6
90 117 1 6
88 119 1 6
99 118 2 6
12 118 2 6
90 117 1 6
22 115 2 6
99 115 2 6
99 118 2 5
12 118 2 5
90 117 1 5
22 115 2 5
99 115 2 5
90 117 1 3
22 115 2 3
99 115 2 3
22 115 2 2
99 115 2 2
函数还有一个带有给定签名的方法apply
:
val f: Int => String = _.toString
f(5) == f.apply(5)
因此,要使用它,您应该compose
(或使用中缀符号trait Function1[In, Out] { // A => B is actually syntactic sugar for Function1[A, B]
def compose[Before](that: Before => In): Before => Out
}
),其中fun1.compose(fun2)
实际上是第一个要应用的函数(这是相同的奇怪排序你有数学经验。)
编辑
要知道组成函数的顺序,让我们解析类型(我将fun1 compose fun2
用于类型相等,尽管它在代码中没有意义):
fun2
因此==
有正确的签名作为f: OpenExpAlg[S, S] == (=> ExpAlg[S]) => GexpAlg[S, Open[S, S]]
closeAlg[S]: OExpAlg[S, S] => ExpAlg[S] == GExpAlg[S, Open[S,S]] => ExpAlg[S]
的参数。
但是,您仍然遇到问题,因为(closeAlg[S] compose f): (=> ExpAlg[S]) => ExpAlg[S] == Open[ExpAlg[S]]
不是函数,而是封闭结构的方法。编译器通常在两者之间进行转换,但有时可能会遇到一些麻烦。为了帮助它,你应该做
fix
此closeAlg
表示法强制将该方法视为函数。