这段代码出了什么问题....“compose”

时间:2017-05-29 16:15:40

标签: scala

我正在努力完成部分工作 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 _))

1 个答案:

答案 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表示法强制将该方法视为函数。