所以我试图在Haskell中生成一个出租车编号列表.出租车编号是可以用两种不同方式写成两个不同立方体之和的数字 - 最小的是
1729 = 1^3 + 12^3 = 9^3 + 10^3.
现在,我只是生成了四个"组成"出租车编号的数字,例如(1,12,9,10),并被告知使用列表理解(我不太熟悉) ).此函数将生成所有4元组,其中最大数字最多为n:
taxi n = [(a,b,c,d) | a <- [1..n], b <- [1..n], c <- [1..n], d <- [1..n], a^3 + b^3 == c^3 + d^3, a < b, a < c, c < d]
但是,由于以下几个原因,它很麻烦:
[1..n]只写一次.a <- [1..]等等,那么程序永远不会最终评估任何东西.taxi 5019秒.任何速度优化也都会很好,但如果不是我使用的天真方法就足够了.
所以我试图定义我自己的数据类型,它递归地表达自然数,如下所示:
data Nat = Zero | Succ Nat
Run Code Online (Sandbox Code Playgroud)
此功能正常工作:
showNat :: Nat -> String
showNat Zero = "Zero"
showNat (Succ k) = "Succ " ++ (showNat k)
Run Code Online (Sandbox Code Playgroud)
但是,我不想每次要向屏幕输出 Nat 时都必须调用它。我试过这个:
instance Show Nat where
show Zero = "Zero"
show (Succ k) = "Succ " ++ Main.show k
Run Code Online (Sandbox Code Playgroud)
但它返回一个错误:
• No explicit implementation for
either ‘showsPrec’ or ‘Prelude.show’
• In the instance declaration for ‘Show Nat’
|
| > instance Show Nat where | ^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
如何正确编写“Show”的实例?
考虑这个功能
f g h x y = g (g x) (h y)
Run Code Online (Sandbox Code Playgroud)
它的类型是什么?显然我可以:t f用来查找,但如果我需要手动推断,那么最好的方法是什么呢?
我已经展示的方法是为参数分配类型并从那里推导 - 例如x :: a,y :: b给我们g :: a -> c和h :: b -> d某些c,d(从g x,h y),然后我们继续从那里(c = a从g (g x) (h y)等)进行推论.
然而,这有时只会变成一个巨大的混乱,我常常不确定如何进一步扣除或在我完成后解决.其他问题有时会发生 - 例如,在这种情况下x会变成一个函数,但在作弊和查找类型之前,这对我来说并不明显.
是否有一个特定的算法将始终有效(并且人类可以快速执行)?否则,是否有一些我缺少的启发式或技巧?