Skip to content

Instantly share code, notes, and snippets.

@alskipp
Last active November 14, 2015 09:12
Show Gist options
  • Save alskipp/b77b61381576b15ef4ec to your computer and use it in GitHub Desktop.
Save alskipp/b77b61381576b15ef4ec to your computer and use it in GitHub Desktop.
NATO Phonetic Alphabet – Haskell vs Swift
import Data.Char
import Data.Maybe
letters :: [(Char, String)]
letters = [
('A', "Alpha"), ('B', "Bravo"), ('C', "Charlie"),
('D', "Delta"), ('E', "Echo"), ('F', "Foxtrot"),
('G', "Golf"), ('H', "Hotel"), ('I', "India"),
('J', "Juliett"),('K', "Kilo"), ('L', "Lima"),
('M', "Mike"), ('N', "November"),('O', "Oscar"),
('P', "Papa"), ('Q', "Quebec"), ('R', "Romeo"),
('S', "Sierra"), ('T', "Tango"), ('U', "Uniform"),
('V', "Victor"), ('W', "Whiskey"), ('X', "X-ray"),
('Y', "Yankee"), ('Z', "Zulu")
]
nato :: String -> String
nato = unwords . mapMaybe (flip lookup letters . toUpper)
hello = nato "hello world" -- "Hotel Echo Lima Lima Oscar Whiskey Oscar Romeo Lima Delta"
import Foundation
//: A version of Haskell's catMaybes – could do with a better name!
func catSomes<A>(xs:[A?]) -> [A] {
return reduce(xs, []) { acc, x in
x.map { acc + [$0] } ?? acc
}
}
let letters = [
"A" : "Alpha", "B" : "Bravo", "C" : "Charlie",
"D" : "Delta", "E" : "Echo", "F" : "Foxtrot",
"G" : "Golf", "H" : "Hotel", "I" : "India",
"J" : "Juliett","K" : "Kilo", "L" : "Lima",
"M" : "Mike", "N" : "November","O" : "Oscar",
"P" : "Papa", "Q" : "Quebec", "R" : "Romeo",
"S" : "Sierra", "T" : "Tango", "U" : "Uniform",
"V" : "Victor", "W" : "Whiskey", "X" : "X-ray",
"Y" : "Yankee", "Z" : "Zulu"
]
func nato(str:String) -> String {
return join(" ", catSomes(map(str) { letters[String($0).uppercaseString] }))
}
nato("hello world") // Hotel Echo Lima Lima Oscar Whiskey Oscar Romeo Lima Delta
//: A version with 'mapSome' function and a couple more helper funcs to improve readability
import Foundation
//: A version of Haskell's mapMaybe for CollectionTypes – returns Array
func mapSome<C: CollectionType, T>(source: C, f: C.Generator.Element -> T?) -> [T] {
return reduce(source, []) { acc, x in
f(x).map { acc + [$0] } ?? acc
}
}
//: beaky operator for applying args to functions left to right
infix operator |> {associativity left}
func |> <A,B>(x:A, g: A -> B) -> B {
return g(x)
}
//: needed when using 'beaky' operator with functions taking 2 args
func curry<A,B,C>(f:((A,B) -> C)) -> A -> B -> C {
return { a in { b in f(a, b) } }
}
let letters = [
"A" : "Alpha", "B" : "Bravo", "C" : "Charlie",
"D" : "Delta", "E" : "Echo", "F" : "Foxtrot",
"G" : "Golf", "H" : "Hotel", "I" : "India",
"J" : "Juliett","K" : "Kilo", "L" : "Lima",
"M" : "Mike", "N" : "November","O" : "Oscar",
"P" : "Papa", "Q" : "Quebec", "R" : "Romeo",
"S" : "Sierra", "T" : "Tango", "U" : "Uniform",
"V" : "Victor", "W" : "Whiskey", "X" : "X-ray",
"Y" : "Yankee", "Z" : "Zulu"
]
func nato(str:String) -> String {
return mapSome(str) { letters[String($0).uppercaseString] } |> curry(join)(" ")
}
nato("hello world") // Hotel Echo Lima Lima Oscar Whiskey Oscar Romeo Lima Delta
@alskipp
Copy link
Author

alskipp commented Apr 7, 2015

Thanks to Weissi for suggesting the mapMaybe function in Haskell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment