Created
December 2, 2012 05:12
-
-
Save jdewind/4187046 to your computer and use it in GitHub Desktop.
Hask List Comprehension: Adaptation of Triangle Example in Tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import System.Environment | |
type Triangle = (Int, Int, Int) | |
perimeter :: Triangle -> Int | |
perimeter (a, b, c) = a + b + c | |
rightTriangle :: Triangle -> Bool | |
rightTriangle (a, b, c) = a^2 + b^2 == c^2 | |
rightTriangles :: [Triangle] -> [Triangle] | |
rightTriangles xs = [ x | x <- xs, rightTriangle x] | |
withMultipleOf :: [Triangle] -> Int -> [Triangle] | |
withMultipleOf xs m = [x | x <- xs, mod (perimeter x) m == 0] | |
generateTriangles :: Int -> [Triangle] | |
generateTriangles num = [ (a, b, c) | c <- [1..num], b <- [1..num], a <- [1..num] ] | |
printResults :: [String] -> IO () | |
printResults [num, per] = do | |
print (withMultipleOf (rightTriangles (generateTriangles (read num))) (read per)) | |
printResults args = putStrLn "Wrong number of arguments" | |
main :: IO () | |
main = do | |
args <- getArgs | |
printResults args |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'pp' | |
class Triangle | |
attr_accessor :a, :b, :c | |
def initialize(a, b, c) | |
@a, @b, @c = a, b, c | |
end | |
def right_triangle? | |
@a**2 + @b**2 == @c**2 | |
end | |
def perimeter | |
@a + @b + @c | |
end | |
def self.only_right_triangles(triangles) | |
triangles.select { |x| x.right_triangle? } | |
end | |
def self.right_and_with_perimeter_multiple_of(triangles, multiple) | |
only_right_triangles(triangles).select { |x| x.perimeter % multiple == 0 } | |
end | |
def self.generate(num) | |
triangles = [] | |
range = (1..num).to_a | |
range = range.product range, range | |
range.map { |(a,b,c)| Triangle.new a, b, c } | |
end | |
def inspect | |
"(#{@a}, #{@b}, #{@c})" | |
end | |
end | |
if __FILE__ == $0 | |
if ARGV.count == 2 | |
triangles = Triangle.generate ARGV[0].to_i | |
pp Triangle.right_and_with_perimeter_multiple_of triangles, ARGV[1].to_i | |
else | |
puts "Wrong number of arguments" | |
end | |
end |
Author
jdewind
commented
Dec 2, 2012
- Ruby implementation is far less safe due to its dynamic nature
- It is impossible to pass the wrong type to the Haskell implementation
- Haskell's
read
infers the type passed to the functions - Tuples are types in themselves and Haskell has a nice way of making synonymous types
- Pattern matching in Haskell made handling arguments more elegant
- Ruby appears to be faster in this one particular case
- List comprehension in Haskell is really nice
- I like how both implementations read
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment