小编lea*_*day的帖子

编译器如何计算出仿函数的固定点以及cata如何在叶级工作?

我觉得理解一个仿函数的固定点的抽象概念,但是,我仍然在努力弄清楚它的确切实现及其在Haskell中的变形.

例如,如果我定义,如根据"程序员类别理论"一书 - 第359页,下面的代数

-- (Int, LiftF e Int -> Int)

data ListF e a = NilF | ConsF e a

lenAlg :: ListF e Int -> Int
lenAlg (ConsF e n) -> n + 1
lenAlg NilF = 0
Run Code Online (Sandbox Code Playgroud)

根据catamorphism的定义,可以将以下函数应用于ListF的固定点,即List,以计算其长度.

cata lenAlg :: [e] -> Int
cata lenAlg = lenAlg . fmap (cata lenAlg) . unFix
Run Code Online (Sandbox Code Playgroud)

我有两个困惑.首先,如何Haskell编译知道名单是THE LISTF的固定点?我从概念上知道它是,但是编译器如何知道,即,如果我们定义另一个列表,那就是与List相同的一切,我打赌编译器不会自动推断出List'也是ListF的固定点,或者它?(我会感到惊讶).

其次,由于cata lenAlg的递归性质,它总是试图取消修复数据构造函数的外层以暴露仿函数的内层(我的解释是否正确?).但是,如果我们已经在叶子上,我们怎么能调用这个函数调用呢?

fmap (cata lenAlg) Nil
Run Code Online (Sandbox Code Playgroud)

举个例子,有人可以帮助为下面的函数调用写一个执行跟踪来澄清吗?

cata lenAlg Cons 1 (Cons 2 Nil)
Run Code Online (Sandbox Code Playgroud)

我可能遗漏了一些显而易见的事情,但是我希望这个问题对于其他有类似困惑的人来说仍然有意义.


回答总结


@nm回答了我的第一个问题,指出为了让Haskell编译器弄清楚Functor A是Functor B的一个固定点,我们需要明确.在这种情况下,它是

type …
Run Code Online (Sandbox Code Playgroud)

haskell category-theory catamorphism recursion-schemes fixpoint-combinators

7
推荐指数
2
解决办法
213
查看次数

在这种情况下,是否可以折叠Applicative <*>以避免重复?

在下面的代码中

module Main where

import Control.Monad.State
import Control.Applicative

type Code = String

toSth :: Read a => State [Code] a
toSth = state $ \(c:cs) -> ((read c), cs)

codes = ["12", "True", ""]

data Tick = Tick {n :: Int, bid :: Bool} deriving (Show)

res = runState (pure Tick <*> toSth <*> toSth) codes

main = print res
Run Code Online (Sandbox Code Playgroud)

我得到正确的结果

(Tick {n = 12, bid = True},[""])
Run Code Online (Sandbox Code Playgroud)

但是我的问题是重复

pure Tick <*> toSth <*> toSth
Run Code Online (Sandbox Code Playgroud)

即,如果记录有100个字段,那么我必须写<*> toSth100次,这看起来不像Haskell。

有没有办法来 …

haskell

2
推荐指数
1
解决办法
127
查看次数

如何在 IntelliJ Mac OS 中输入右箭头(即?,不是 =&gt;)?

在 Scala 模式匹配中使用的一个常见符号是右箭头,或者 ? 或 =>。所以我的问题是输入整洁的右箭头的快捷方式是什么?我在 Mac OS 上使用 IntelliJ。

下面是一个使用 ? 来自https://doc.akka.io/docs/akka/current/guide/tutorial_1.html

package com.lightbend.akka.sample

import akka.actor.{ Actor, Props, ActorSystem }
import scala.io.StdIn

class PrintMyActorRefActor extends Actor {
  override def receive: Receive = {
    case "printit" ?
      val secondRef = context.actorOf(Props.empty, "second-actor")
      println(s"Second: $secondRef")
  }
}

object ActorHierarchyExperiments extends App {
  val system = ActorSystem("testSystem")

  val firstRef = system.actorOf(Props[PrintMyActorRefActor], "first-actor")
  println(s"First: $firstRef")
  firstRef ! "printit"

  println(">>> Press ENTER to exit <<<")
  try StdIn.readLine()
  finally system.terminate()
}
Run Code Online (Sandbox Code Playgroud)

scala intellij-idea

1
推荐指数
1
解决办法
669
查看次数

子类logging.Logger的模式

是否有一个共同的模式可以遵循来正确地子类化logging.Logger

import logging

class MyLogger(logging.Logger):
    __init__(self, name):
        super().__init__(name=name)
Run Code Online (Sandbox Code Playgroud)

似乎不起作用属性,因为以MyLogger这种方式创建的属性没有对其父级的引用。虽然我可以手动设置它的父级,但恐怕还有其他协议loggging.Logger不满足MyLogger

python logging subclass

1
推荐指数
1
解决办法
1056
查看次数