I started learning Haskell and Swift. I'm wondering if it's the correct way of thinking in "functional" way?
The problem is to create card deck:
I need to loop through suits and ranks - for every suit create card with given suit and rank. In "imperative" way it'd be:
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))
}
}
Then I tried with pure functions using recursion, it works but, can it be done with less code ?
To me "functional" in Swift is less readable, or probably I'm doing it wrong ...
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)
}
Building on the usage of Haskell's applicative concept and <$> and <*> you might find the following generally useful (I think I've translated correctly, although it's based on arrays not sequences):
// use <^> because <$> is already used
infix operator <^> { associativity left }
public func <^> <T, U>(left:(T)->U, right:[T]) -> [U] {
return map(right) { return left($0) }
}
public func flatten<T>(input:[[T]]) -> [T] {
return input.reduce([], +)
}
infix operator <*> { associativity left }
public func <*> <T, U>(left:[(T)->U], right:[T]) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
Which then allows you to use the following:
let suits : [Character] = [ "C", "D", "H", "S"]
let ranks = Array(2...14)
struct Card {
let suit : Character
let rank : Int
static func build(suit:Character)(rank:Int) -> Card {
return Card(suit: suit, rank:rank)
}
}
Card.build <^> suits <*> ranks
This may not be pretty, and I don't think it is functional programming, but it is less code and it uses Swift's terrific map and reduce functions:
struct Card {
let suit: String
let rank: Int
}
let cards = ["Heart", "Diamond", "Club", "Spade"].reduce([Card]()) { (cards, suit) in
return cards + map(1...13) { rank in return Card(suit: suit, rank: rank) }
}
Swift isn't a functional language. However, you can write swift code in functional style.
func map<T: Collection, U>( _ transform: (T.Iterator.Element) -> U, _ xs: T) -> [U] {
return xs.reduce([U](), {$0 + [transform($1)]})
}
func concatMap<A, B> (_ process: (A)->[B], _ xs: [A]) -> [B] {
return xs.reduce([B](), {$0 + process($1)})
}
infix operator <*>
func <*><A, B>(_ xs: [A], _ ys: [B]) -> [(A, B)]{
let transform: (A, B) -> (A, B) = {($0, $1)}
return concatMap({x in map({transform(x, $0)}, ys)}, xs)
}
struct Card {
let suit : Character
let rank : Int
static func build(_ sr: (s:Character, r:Int)) -> Card {
return Card(suit: sr.0, rank: sr.1)
}
}
func test() {
let suits : [Character] = [ "C", "D", "H", "S"]
let ranks = Array(1...13)
let cards = map(Card.build, suits <*> ranks)
print(cards)
}
If you want to learn Haskell and Swift, you could refer to https://github.com/unchartedworks/HaskellSwift
Related
I'm trying to learn best practices on how to structure a program in a pure functional language (Haskell), but I'm having trouble with an architecture which I find natural but cannot replicate easily in the "pure world".
Let me describe a simple model case: a two-player guessing game.
Game rules
A secret random integer number in [0, 100] is generated.
Players take turns trying to guess the secret number.
If the guess is correct, the player wins.
Otherwise the game tells whether the secret number is larger or smaller than the guess and the possible range for the unknown secret is updated.
My question concerns the implementation of this game where a human player plays against the computer.
I propose two implementations:
logic driven
interaction driven
Logic-driven
In the logic-driven implementation, the execution is driven by the game logic. A Game has a State and some participating Players. The Game::run function makes the players play in turns and updates the game state until completion. The players receive a state in Player::play and return the move they decide to play.
The benefits that I can see of this approach are:
the architecture is very clean and natural;
it abstracts the nature of a Player: a HumanPlayer and a ComputerPlayer are interchangeable, even if the former has to deal with IO, whereas the latter represents a pure computation (you can verify this by putting Game::new(ComputerPlayer::new("CPU-1"), ComputerPlayer::new("CPU-2")) in the main function and watching the computer battle).
Here is a possible implementation in Rust:
use rand::Rng;
use std::io::{self, Write};
fn min<T: Ord>(x: T, y: T) -> T { if x <= y { x } else { y } }
fn max<T: Ord>(x: T, y: T) -> T { if x >= y { x } else { y } }
struct Game<P1, P2> {
secret: i32,
state: State,
p1: P1,
p2: P2,
}
#[derive(Clone, Copy, Debug)]
struct State {
lower: i32,
upper: i32,
}
struct Move(i32);
trait Player {
fn name(&self) -> &str;
fn play(&mut self, st: State) -> Move;
}
struct HumanPlayer {
name: String,
}
struct ComputerPlayer {
name: String,
}
impl HumanPlayer {
fn new(name: &str) -> Self {
Self {
name: String::from(name),
}
}
}
impl ComputerPlayer {
fn new(name: &str) -> Self {
Self {
name: String::from(name),
}
}
}
impl Player for HumanPlayer {
fn name(&self) -> &str {
&self.name
}
fn play(&mut self, _st: State) -> Move {
let mut s = String::new();
print!("Please enter your guess: ");
let _ = io::stdout().flush();
io::stdin().read_line(&mut s).expect("Error reading input");
let guess = s.trim().parse().expect("Error parsing number");
println!("{} guessing {}", self.name, guess);
Move(guess)
}
}
impl Player for ComputerPlayer {
fn name(&self) -> &str {
&self.name
}
fn play(&mut self, st: State) -> Move {
let mut rng = rand::thread_rng();
let guess = rng.gen_range(st.lower, st.upper + 1);
println!("{} guessing {}", self.name, guess);
Move(guess)
}
}
impl<P1, P2> Game<P1, P2>
where
P1: Player,
P2: Player,
{
fn new(p1: P1, p2: P2) -> Self {
let mut rng = rand::thread_rng();
Game {
secret: rng.gen_range(0, 101),
state: State {
lower: 0,
upper: 100,
},
p1,
p2,
}
}
fn run(&mut self) {
loop {
// Player 1's turn
self.report();
let m1 = self.p1.play(self.state);
if self.update(m1) {
println!("{} wins!", self.p1.name());
break;
}
// Player 2's turn
self.report();
let m2 = self.p2.play(self.state);
if self.update(m2) {
println!("{} wins!", self.p2.name());
break;
}
}
}
fn update(&mut self, mv: Move) -> bool {
let Move(m) = mv;
if m < self.secret {
self.state.lower = max(self.state.lower, m + 1);
false
} else if m > self.secret {
self.state.upper = min(self.state.upper, m - 1);
false
} else {
true
}
}
fn report(&self) {
println!("Current state = {:?}", self.state);
}
}
fn main() {
let mut game = Game::new(HumanPlayer::new("Human"), ComputerPlayer::new("CPU"));
game.run();
}
Interaction-driven
In the interaction-driven implementation, all the functionalities related to the game, including the decisions taken by the computer players, must be pure functions without side effects. HumanPlayer becomes then the interface through which the real person sitting in front of the computer interacts with the game. In a certain sense, the game becomes a function mapping user input to an updated state.
This is the approach that, to my eyes, seems to be forced by a pure language, because all the logic of the game becomes a pure computation, free of side effects, simply transforming an old state to a new state.
I kind of like also this point of view (separating input -> (state transformation) -> output): it definitely has some merits, but I feel that, as can be easily seen in this example, it breaks some other good properties of the program, such as the symmetry between human player and computer player. From the point of view of the game logic, its doesn't matter whether the decision for the next move comes from a pure computation performed by the computer or a user interaction involving IO.
I provide here a reference implementation, again in Rust:
use rand::Rng;
use std::io::{self, Write};
fn min<T: Ord>(x: T, y: T) -> T { if x <= y { x } else { y } }
fn max<T: Ord>(x: T, y: T) -> T { if x >= y { x } else { y } }
struct Game {
secret: i32,
state: State,
computer: ComputerPlayer,
}
#[derive(Clone, Copy, Debug)]
struct State {
lower: i32,
upper: i32,
}
struct Move(i32);
struct HumanPlayer {
name: String,
game: Game,
}
struct ComputerPlayer {
name: String,
}
impl HumanPlayer {
fn new(name: &str, game: Game) -> Self {
Self {
name: String::from(name),
game,
}
}
fn name(&self) -> &str {
&self.name
}
fn ask_user(&self) -> Move {
let mut s = String::new();
print!("Please enter your guess: ");
let _ = io::stdout().flush();
io::stdin().read_line(&mut s).expect("Error reading input");
let guess = s.trim().parse().expect("Error parsing number");
println!("{} guessing {}", self.name, guess);
Move(guess)
}
fn process_human_player_turn(&mut self) -> bool {
self.game.report();
let m = self.ask_user();
if self.game.update(m) {
println!("{} wins!", self.name());
return false;
}
self.game.report();
let m = self.game.computer.play(self.game.state);
if self.game.update(m) {
println!("{} wins!", self.game.computer.name());
return false;
}
true
}
fn run_game(&mut self) {
while self.process_human_player_turn() {}
}
}
impl ComputerPlayer {
fn new(name: &str) -> Self {
Self {
name: String::from(name),
}
}
fn name(&self) -> &str {
&self.name
}
fn play(&mut self, st: State) -> Move {
let mut rng = rand::thread_rng();
let guess = rng.gen_range(st.lower, st.upper + 1);
println!("{} guessing {}", self.name, guess);
Move(guess)
}
}
impl Game {
fn new(computer: ComputerPlayer) -> Self {
let mut rng = rand::thread_rng();
Game {
secret: rng.gen_range(0, 101),
state: State {
lower: 0,
upper: 100,
},
computer,
}
}
fn update(&mut self, mv: Move) -> bool {
let Move(m) = mv;
if m < self.secret {
self.state.lower = max(self.state.lower, m + 1);
false
} else if m > self.secret {
self.state.upper = min(self.state.upper, m - 1);
false
} else {
true
}
}
fn report(&self) {
println!("Current state = {:?}", self.state);
}
}
fn main() {
let mut p = HumanPlayer::new("Human", Game::new(ComputerPlayer::new("CPU")));
p.run_game();
}
Conclusion
An effectful language (such as Rust) gives us the flexibility to choose the approach based on our priorities: either symmetry between human and computer players or sharp separation between pure computation (state transformation) and IO (user interaction).
Given my current knowledge of Haskell, I cannot say the same about the pure world: I feel forced to adopt the second approach, because the first one would be littered with IO everywhere. In particular, I would like the hear some words from some functional programming gurus on how to implement in Haskell the logic-driven approach and what are their opinions/comments on the subject.
I'm prepared to learn a lot of insight from this.
I suppose the Haskell equivalent of your Logic-Driven implementation (with error handling omitted) is something like this:
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE FlexibleContexts #-}
import System.Random
import Control.Monad
import Control.Monad.State
import Control.Monad.Trans.Maybe
data Game = Game Int Range Player Player
type Range = (Int, Int)
data Player = Player String (Range -> IO Int)
humanPlayer, computerPlayer :: String -> Player
humanPlayer nam = Player nam strategy
where strategy _ = do
putStrLn "Please enter your guess:"
readLn
computerPlayer nam = Player nam strategy
where strategy s = do
x <- randomRIO s
putStrLn $ nam ++ " guessing " ++ show x
return x
newGame :: Player -> Player -> IO Game
newGame p1 p2 = do
let s = (0,100)
x <- randomRIO s
return $ Game x s p1 p2
run :: Game -> IO ()
run (Game x s0 p1 p2)
= do Nothing <- runMaybeT $ evalStateT game s0
return ()
where
game = mapM_ runPlayer $ cycle [p1, p2]
runPlayer (Player nam strat) = do
s#(lo,hi) <- get
liftIO . putStrLn $ "Current state = " ++ show s
guess <- liftIO $ strat s
put =<< case compare x guess of
LT -> return (lo, guess-1)
GT -> return (guess+1, hi)
EQ -> do
liftIO . putStrLn $ nam ++ " wins!"
mzero
main :: IO ()
main = run =<< newGame (humanPlayer "Human") (computerPlayer "Computer")
We could tear our hair, rend our clothes, and moan pitifully that we had to use liftIOs in a few places and that the monad transformer stack hurts our tummies, but it mostly looks like idiomatic Haskell code to me, except perhaps that using MaybeT to end a loop is a little ugly. (Like many Haskell programmers who should know better, I got swept up in the pleasing form of the minor expression mapM_ runPlayer $ cycle [p1, p2] and wrote a silly monad stack to accommodate it.)
I guess I find it a little disingenuous to argue that, on the one hand, in an effectful language like Rust we can effortlessly mix pure and impure code because the pure code is actually written in an impure language, but for some reason if we try to write the same code in Haskell, we are bound by God and Country to write our pure code outside the IO monad and then bemoan the fact that we can't do IO there and so our implementation choices are suddenly limited. Writing "pure" code in an impure context isn't a capital offense, in Haskell or any other language.
In particular, you can easily write an obviously pure player for this implementation:
purePlayer :: String -> Player
purePlayer nam = Player nam (return . pureStrategy)
where pureStrategy :: Range -> Int
pureStrategy (lo, hi) = (lo + hi) `div` 2
or, if you're a zealot, you could make the above code polymorphic in the base monad, and use IO for the human but Identity for the purePlayer. Ta da, your pure player is now truly pure, and you can tell all your dimwitted, effectful Rust friends that you're so much better than they are while boasting to your genius, pure Haskell friends that you just figured out why they invented UnliftIO.
I have something which I know is a tuple. How do I generically append a single value to the tuple?
let some_tuple: (i32, &str, bool) = (1, "Hello", true);
let with_world: (i32, &str, bool, &str) = some_tuple.append("World");
As a possible use-case, consider a parser combinator which takes a variadic number of parsers and runs each in sequence, producing a tuple of their attributes:
// Emulate variadic parameters:
macro_rules! seq {
($($parsers:expr),*) => {
move |input: &[u8]| {
let result = ();
let remaining = input;
$(
let (remaining, parser_result) = $parsers(remaining);
let result = result.append(parser_result);
)*
result
}
}
}
With tuple appending, seq!(a, b, c, d) can yield (A, B, C, D), rather than the ugly (((A, B), C), D).
As an alternative to a tuple, consider using an HList:
use frunk::hlist; // 0.3.0
fn main() {
let some_values = hlist![1, "Hello", true];
let with_world = some_values.prepend("World");
println!("{:?}", with_world);
}
There's no built-in way to do this, but we can implement it ourselves with a helper trait and a macro to implement that trait for tuples up to N arguments:
trait TupleAppend<T> {
type ResultType;
fn append(self, t: T) -> Self::ResultType;
}
impl<T> TupleAppend<T> for () {
type ResultType = (T,);
fn append(self, t: T) -> Self::ResultType {
(t,)
}
}
macro_rules! impl_tuple_append {
( () ) => {};
( ( $t0:ident $(, $types:ident)* ) ) => {
impl<$t0, $($types,)* T> TupleAppend<T> for ($t0, $($types,)*) {
// Trailing comma, just to be extra sure we are dealing
// with a tuple and not a parenthesized type/expr.
type ResultType = ($t0, $($types,)* T,);
fn append(self, t: T) -> Self::ResultType {
// Reuse the type identifiers to destructure ourselves:
let ($t0, $($types,)*) = self;
// Create a new tuple with the original elements, plus the new one:
($t0, $($types,)* t,)
}
}
// Recurse for one smaller size:
impl_tuple_append! { ($($types),*) }
};
}
impl_tuple_append! {
// Supports tuples up to size 10:
(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
}
Playground
As I continue to learn Rust I'm working on a project which involves extensive use of predicate functions. I've decided to implement these predicates with Rust closures, e.g.:
type Predicate = Box<Fn(&Form) -> bool>.
My program uses boolean logic applied to these predicates. For instance, both and as well as or are applied over the value of these predicates. I've made this work using Box::leak:
struct Form {
name: String,
}
fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
if a.is_none() {
return b;
} else if b.is_none() {
return a;
} else {
let a = Box::leak(a.unwrap());
let b = Box::leak(b.unwrap());
return Some(Box::new(move |form: &Form| a(form) && b(form)));
}
}
While this seems to work as I'd like, Box::leak seems non-ideal. I don't know enough about std::rc::Rc and std::cell::RefCell to know if these might help me avoid Box::leak here — employing them might require significant restructuring of my code, but I'd like to at least understand what the idiomatic approach here might be.
Is there a way of avoiding the leak while still maintaining the same functionality?
Here's the complete example:
struct Form {
name: String,
}
type Predicate = Box<Fn(&Form) -> bool>;
struct Foo {
predicates: Vec<Predicate>,
}
impl Foo {
fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
if a.is_none() {
return b;
} else if b.is_none() {
return a;
} else {
let a = Box::leak(a.unwrap());
let b = Box::leak(b.unwrap());
return Some(Box::new(move |form: &Form| a(form) && b(form)));
}
}
}
fn main() {
let pred = Foo::and(
Some(Box::new(move |form: &Form| {
form.name == String::from("bar")
})),
Some(Box::new(move |_: &Form| true)),
)
.unwrap();
let foo = Foo {
predicates: vec![pred],
};
let pred = &foo.predicates[0];
let form_a = &Form {
name: String::from("bar"),
};
let form_b = &Form {
name: String::from("baz"),
};
assert_eq!(pred(form_a), true);
assert_eq!(pred(form_b), false);
}
Your code does not need Box::leak and it's unclear why you think it does. The code continues to compile and have the same output if it's removed:
impl Foo {
fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
if a.is_none() {
b
} else if b.is_none() {
a
} else {
let a = a.unwrap();
let b = b.unwrap();
Some(Box::new(move |form: &Form| a(form) && b(form)))
}
}
}
The unwraps are non-idiomatic; a more idiomatic solution would use match:
impl Foo {
fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
match (a, b) {
(a, None) => a,
(None, b) => b,
(Some(a), Some(b)) => Some(Box::new(move |form| a(form) && b(form))),
}
}
}
I am new to Go (coming from python) and I am having a bit of a hard time here. I am trying to allow any type of slice into my struct/func and it just contains a count of the length of that slice.
import "go/types"
type Response struct {
Count int `json:"count"`
Results []types.Struct `json:"results`
}
func NewResponse(results []types.Struct) (r *Response) {
r.Count = len(results)
r.Results = results
return
}
you can use interface{} as any type.
type Response struct {
Count int `json:"count"`
Results []interface{} `json:"results`
}
UPDATE
len(rsp.results) should work.
http://play.golang.org/p/RA2zVzWl2q
Arbitrary types are totally legit in Go. In your case, it might be appropriate to use []interface{} as the type of Results. When ever the types need to be known, use type switch.
package main
import (
"fmt"
)
type Response struct {
Count int `json:"count"`
Results []interface{} `json:"results`
}
func NewResponse(results []interface{}) (r *Response) {
r.Count = len(results)
r.Results = results
return
}
func AssertResultType(results []interface{}) {
for _, v := range results {
switch v := v.(type) {
default:
fmt.Printf("unexpected type %T\n", v) //t has unexpected type
case bool:
fmt.Printf("boolean %t\n", v) // t has type bool
case int:
fmt.Printf("integer %d\n", v) // t has type int
case string:
fmt.Printf("string %q\n", v) // t has type string
}
}
}
func main() {
args := []interface{}{1, "hello", true, "foo", 21}
r := NewResponse(args)
AssertResultType(r.Results)
}
In case of JSON, *json.RawMessage can be marshaled to type []byte
type Response struct {
Count int `json:"count"`
Results *json.RawMessage `json:"results`
}
I'd like to write this:
fn fibs() -> std::iter::Iterator<int> {
return std::iter::iterate((1i, 1i), |(a, b)| { (b, a + b) }).map(|(a, _)| a)
}
But if I do, I get this error:
error: explicit lifetime bound required
fn fibs() -> std::iter::Iterator<int> {
^^^^^^^^^^^^^^^^^^^^^^^^
If, instead I write out the full interface, it compiles:
fn fibs() -> std::iter::Map<'static, (int, int), int, std::iter::Iterate<'static, (int, int)>> {
return std::iter::iterate((1i, 1i), |(a, b)| { (b, a + b) }).map(|(a, _)| a)
}
Is there a way to return the simpler interface?
There is not at present any way to return an abstract type such as Iterator<T>, just as you can’t assign that as the type of a variable (let x: Iterator<uint>; won’t compile for the same reasons).
This has been discussed and is certainly desired; when it is done it will probably be in the form fn fibs() -> impl Iterator<uint>, but you can’t do that yet.
as #ChrisMorgan said, for now you can't return an abstract type. If you are creating a public API and want to avoid depending too much on the specific implementation of iterate and map, you can encapsulate the return type into your own struct (which is more or less what the collections in the std library themselves do).
Something like:
// updated to rustc 0.13.0-nightly (2015-01-02)
use std::iter::{Map, iterate, Unfold};
type Fibs = Map<(int, int), int, Unfold<(int, int),
(fn((int, int)) -> (int, int), Option<(int, int)>, bool),
fn(&mut (fn((int, int)) -> (int, int), Option<(int, int)>, bool)) ->
Option<(int, int)>>, fn((int, int)) -> int>;
struct Fibs2 {
iter: Fibs,
}
impl Fibs2 {
fn iter() -> Fibs2 {
fn inner((a, b): (int, int)) -> (int, int) { (b, a + b) }
let in_fn = inner as fn((int, int)) -> (int, int);
fn first((a, _): (int, int)) -> int { a }
let p_first = first as fn((int, int)) -> int;
Fibs2{ iter: iterate((1i, 1i), in_fn).map(p_first) }
}
}
impl Iterator<int> for Fibs2 {
fn next(&mut self) -> Option<int> {
self.iter.next()
}
}
fn main() {
for fib_n in Fibs2::iter().take(10) {
println!("{}", fib_n);
}
}