【发布时间】:2015-01-06 22:18:39
【问题描述】:
我开始学习 Haskell 和 Swift。我想知道这是否是以“功能”方式思考的正确方式? 问题是创建卡片组: 我需要遍历套装和等级 - 为每个套装创建具有给定套装和等级的卡片。以“势在必行”的方式:
let suits: Array<Character> = ...
let ranks: Array<Int> = ...
var cards: [Card]
for suit in suits {
for rank in ranks {
cards.addObject(Card(suit: suit, rank: rank))
}
}
然后我尝试使用递归的纯函数,它可以工作,但是可以用更少的代码来完成吗? 对我来说,Swift 中的“函数式”可读性较差,或者我可能做错了......
let cards = cardsWithSuits(suits, ranks, [Card]());
func cardsWithSuits(suits: [Character], ranks: [Int], cards: [Card]) -> [Card] {
if suits.count == 0 { return cards }
let suit: Character = head(suits)!
let acc = cardsWithRanks(ranks, suit, cards)
return cardsWithSuits(drop(1, suits), ranks, acc)
}
func cardsWithRanks(ranks: [Int], suit: Character, cards: [Card]) -> [Card] {
if ranks.count == 0 { return cards }
let acc = cards + [Card(suit: suit, rank: head(ranks)!)]
return cardsWithRanks(drop(1, ranks), suit, acc)
}
【问题讨论】:
-
在 Haskell 中,您可能会使用列表解析:
[Card s r | s <- suits, r <- ranks]。你也可以利用 list 是一个 Applicative 的事实并写Card <$> suits <*> ranks虽然工作的原因有点远不明显。 -
以上转换为
concat (concat (map (\suit -> map (\rank -> Card rank suit) ranks) suits)),顺便说一句,这可能在Swift中更直接可以实现。 -
Haskell 更加简洁,不幸的是在 Swift 中没有类似的语法。我在看了 Haskell 教程之后在上面写了,然后我实现了一些简单的 Haskell 函数。在 swift (head, drop ...) 中尝试我是否可以在 swift 中做到这一点,但在 swift 中它更加冗长。
-
哪个是其他人最易读/最容易理解的?这是决定好代码的指标。
标签: haskell swift functional-programming