我觉得理解一个仿函数的固定点的抽象概念,但是,我仍然在努力弄清楚它的确切实现及其在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
在下面的代码中
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。
有没有办法来 …
在 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) 是否有一个共同的模式可以遵循来正确地子类化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?