"子类型必须可替代其基类型"
假设我已经有了Bird类,并且:
class Parrot extends Bird {
public function Talk() {
echo 'Talk';
}
}
Run Code Online (Sandbox Code Playgroud)
鸟不能说话,所以我无法用鸟取代鹦鹉.
这只是一个基本的例子,但通常扩展类可以比基类做得更多.我错过了什么?
我需要定义一个名为(get-all-pairs key seq)的函数
它返回seq中所有以第一个元素为键的对的列表.如果没有对匹配,则返回空列表.
例如,如果我说宠物
(def pets
'((cat 1) (dog 1) (fish 1) (cat 2) (fish 2))
)
Run Code Online (Sandbox Code Playgroud)
(get-all-pairs 'cat pets)返回((cat 1) (cat 2))并(get-all-pairs 'bird pets)返回'().
这是我的尝试:
(defn get-all-pairs [key seq]
(cond
(= key (first(first(seq)))) (cons (first seq)
(get-all-pairs key (rest seq)))
:else '()))
Run Code Online (Sandbox Code Playgroud)
但它不起作用.如果我打电话给它,它的消息如下:
#'proj2.proj2/pets
=> (get-all-pairs 'cat pets)
ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn proj2.proj2/get-all-pairs (proj2.clj:20)
Run Code Online (Sandbox Code Playgroud)
我不知道问题出在哪里.怎么解决?
我正在阅读制作我们自己的类型和类型类来学习你的哈克尔.
在代数数据类型介绍中我注意到:
data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Point Point deriving (Show)
surface :: Shape -> Float
surface (Rectangle (Point x1 y1) (Point x2 y2)) = abs (x2 - x1) * abs (y2 - y1)
Run Code Online (Sandbox Code Playgroud)
在surface (Rectangle (Point x1 y1) (Point x2 y2)),我们指出Rectangle的参数是Point类型.
但是,在递归数据结构部分中:
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
singleton :: …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个生成Clojure的宏,deftype并且需要生成类型提示.我目前有一些测试代码:
(defmacro test-macro [n]
(let [obj-sym (gensym "obj")
p0 (with-meta 'p0 {:tag java.lang.Object})
p1 (with-meta 'p1 {:tag java.lang.Integer/TYPE})
r0 (with-meta 'remove {:tag java.lang.Boolean/TYPE})
r1 (with-meta 'remove {:tag java.lang.Object})]
`(deftype ~n [~obj-sym]
java.util.List
(~r0 [_ ~p0] (.remove ~obj-sym ~p0))
(~r1 [_ ~p1] (.remove ~obj-sym ~p1)))))
Run Code Online (Sandbox Code Playgroud)
当它返回时:
(test-macro test-it)
;clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: Must hint overloaded method: remove, ...
Run Code Online (Sandbox Code Playgroud)
作为指导,它应该产生相当于:
(clojure.core/deftype ThisWorks [obj-5546]
java.util.List
(#^"boolean" remove [_ ^java.lang.Object p0-object] (.remove obj-5546 p0-object))
(^{:tag "java.lang.Object"} remove [_ ^int p0-int] (.remove obj-5546 p0-int)))
Run Code Online (Sandbox Code Playgroud)
看起来我的类型暗示了错误的东西,或者元数据没有被传递.除了针对当前问题的修复之外,如果你可以帮助解决更普遍的"元"问题,那么奖励积分:如何调试操作元数据的宏作为宏扩展在这里不是很有用.. …
我有一个文本文件,每行包含一个 json 值。我的文件如下:
{"id":"a","family":"root","parent":nil,"value":"valueofa"}
{"id":"b1","family":"b","parent":"a","value":"valueofb1"}
{"id":"c1","family":"c","parent":"b1","value":"valueofc1"}
{"id":"c2","family":"c","parent":"b1","value":"valueofc2"}
{"id":"b2","family":"b","parent":"root","value":"valueofb2"}
{"id":"d1","family":"d","parent":"b1","value":"valueofd1"}
Run Code Online (Sandbox Code Playgroud)
在上面给出的 json 中,我们的 family 属性表示一个层次结构,我们将“root”作为根,“b”作为“root”的孩子,“c”作为“b”和“d”的孩子也是“b”的孩子。
这个想法是遍历文件并在树中的适当位置添加正在读取的节点。一种方法是将这些条目读入“地图”,然后将此地图用于任何树操作。对于任何复杂的树操作,我不确定这将如何工作。很有可能根据某个要求,我可能必须将子项与现有父项分离并将其附加到另一个父项。显然 Clojure 拉链应该在这方面有所帮助,但我对拉链中节点的层次结构如何工作感到有些困惑。
如果有人能在这里指出我正确的方向,那就太好了。
如果我在Haskell中有一个单独的链表:
data LL a = Empty | Node a (LL a) deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)
我可以轻松地实现在结尾和开头插入的方法.但是在特定元素之后或之前插入呢?如果我有一个LL的Integer,我可以在Haskell区分之间插入4含有特定的节点之后1,而不是第一个1,它处理列表时看到的?
Node 1 (Node 2 (Node 3 (Node 1 Empty)))
Run Code Online (Sandbox Code Playgroud)
我很好奇一个insertAfter方法看起来如何能够指定"在包含1的特定节点之后插入5".如果我想在第一个节点包含之后插入1,我是否必须传入整个列表来指定它,并且仅针对最后一个节点Node 1 Empty?
我不确定将此作为"对象相等"来解决是否正确 - 但我想知道是否有一种方法可以在这样的数据结构中引用具有相同有效负载的类型的特定元素.
我正在尝试编写一个函数来将0和50之间的所有3和5的倍数相加,但是当我告诉它时,Clojure似乎决定不将正确的值添加到我的列表中.
该(conj toSum counter)表单应该将当前数字附加到toSum数组,并且当循环退出时,(reduce + toSum)表单应该将数组中的所有内容一起添加.
就目前而言,当reduce调用函数时,toSum它总是为空的,因为conj函数没有按照它应该做的那样做.我必须搞砸我的逻辑,但我似乎无法弄明白.
(defn calculate [target]
(loop [counter target
toSum []]
(if (= 0 counter)
(reduce + toSum)
(if (or (= 0 (mod counter 3)) (= 0 (mod counter 5)))
(do (conj toSum counter)
(println toSum)
(recur (dec counter) toSum))
(recur (dec counter) toSum)))))
Run Code Online (Sandbox Code Playgroud) 我有一个我试图在这里运行的powerset实现:http://rextester.com/runcode .我仍然遇到这个错误,无法弄清楚如何使它正确.我试图尽可能多地阅读有关哈希尔的IO,但这对我来说太难了.
import Control.Monad (filterM)
powerset = filterM (const [True, False])
main = powerset[1,2]
Run Code Online (Sandbox Code Playgroud) 我发现很多"特殊形式"只是在背景中使用星号版本的宏(fn*,let*和所有其他版本).
例如,在fn的情况下,它将解构能力添加到fn*单独不提供的混合中.我试图找到一些关于fn*可以和不能自己做什么的详细文档,但我没那么幸运.
它肯定支持:
&/ catchall指标
(fn* [x & rest] (do-smth-here...))
Run Code Online (Sandbox Code Playgroud)并且好奇地还有arity的超载,如:
(fn* ([x] (smth-with-one-arg ...)
([x y] (smth-with-two-args ...))
Run Code Online (Sandbox Code Playgroud)所以我的问题最终是,为什么不定义:
(fn& [& all-args] ...)
Run Code Online (Sandbox Code Playgroud)
这将是绝对最小的,可以通过宏提供所有arity选择(检查参数列表的大小,if/case语句直接代码路径,将前几个参数绑定到所需的符号等).
这是出于性能原因吗?也许有人甚至有一个链接到星号特殊形式的实际标准定义方便.
最近几周我刚刚开始学习 Haskell。我正在使用 Project Euler 问题来学习,目前正在尝试弄清楚是否有可能。不找人给我答案,只需要帮助理解 Haskell 中的数据结构。
我目前正在处理问题 484,它指定了一个递归函数。编写函数不是问题,我目前有:
import Math.NumberTheory.Primes
import Data.Maybe
import Data.List
derivative :: Integer -> Integer
derivative x
| x < 2 = error "Error: Attempt to evaluate outside domain"
| isPrime x = 1
| otherwise = (derivative a)*b + a*(derivative b)
where
[a, b] = int_split x
--this function find the first pair of divisors
int_split :: Integer -> [Integer]
int_split n = [first_div, n `div` first_div] where
first_div = fromJust $ …Run Code Online (Sandbox Code Playgroud)