is haskell an acceptable perl?
TRANSCRIPT
![Page 1: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/1.jpg)
Is Haskell an Acceptable Perl?
@osfameron
LambdaLounge MadLab 18 April 2016
https://github.com/osfameron/haskell-perl
![Page 2: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/2.jpg)
Overview
Perl:
https://www.perl.org/
Perl 5 is a highly capable, feature-rich programming language with over 27 years of development
Haskell:
https://www.haskell.org/
An advanced purely-functional programming language
An open source community effort for over 20 years
![Page 3: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/3.jpg)
Received Wisdom?
Perl:
dynamic
messy
simple
flexible
Haskell:
static
clean
hard
mathsy
![Page 4: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/4.jpg)
Received Wisdom?
Perl:
dynamic
messy
simple
flexible
$?=~s/(?:[%^]+)/a/gsmx;
Haskell:
static
clean
hard
mathsy
a>>=(c@(_ _)->b’$c:[d])
![Page 5: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/5.jpg)
Comparison
Perl:
Imperative
OO
Functional
“Weakly typed”
Real World
Haskell:
- (or best?)
-
Purely Functional
Strongly typed
?
![Page 6: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/6.jpg)
Comparison
Perl:
Imperative
OO
Functional
“Weakly typed”
Real World
“whipuptitude”
Haskell:
- (or best?)
-
Purely Functional
Strongly typed
?
“manipulexity”
![Page 7: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/7.jpg)
“Around 1993 I started reading books about Lisp, and I discovered something important:
Perl is much more like Lisp than it is like C.”
![Page 8: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/8.jpg)
What Makes Lisp Different?
“…describes seven features of Lisp.
Perl shares six of these features; C shares none of them.
These are big, important features, features like first-class functions, dynamic access to the symbol table, and automatic storage management.”
-- mjd
![Page 9: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/9.jpg)
Perl6:
1st implementation (Pugs) written in Haskell!
Many Haskell ideas influenced design of Perl6.
![Page 10: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/10.jpg)
GHC:
Used Perl to prototype early versions of key components
(the Evil Mangler, etc.)
still required for “boot” script to build ghc from source
![Page 11: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/11.jpg)
![Page 12: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/12.jpg)
Example:
??? (“Annie”, “Bob”, “Chandra”)
=> (5, 3, 7)
![Page 13: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/13.jpg)
Example:
map ??? (“Annie”, “Bob”, “Chandra”)
=> (5, 3, 7)
![Page 14: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/14.jpg)
Example:
map length, (“Annie”, “Bob”, “Chandra”)
=> (5, 3, 7)
![Page 15: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/15.jpg)
Perl vs Haskell?
??? map length,
(“Annie”, “Bob”, “Chandra”)
![Page 16: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/16.jpg)
Map
map length,
(“Annie”, “Bob”, “Chandra”)
map length
[“Annie”, “Bob”, “Chandra”]
![Page 17: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/17.jpg)
Map
map length,
(“Annie”, “Bob”, “Chandra”)
map length
[“Annie”, “Bob”, “Chandra”]
length :: String -> Int
length “Annie” => 5
map length :: [String]->[Int]
map :: (a -> b) -> [a] -> [b]
![Page 18: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/18.jpg)
Map
map length,
(“Annie”, “Bob”, “Chandra”)
# map EXPR, LIST
# map BLOCK LIST
map { length } (…)
map length
[“Annie”, “Bob”, “Chandra”]
![Page 19: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/19.jpg)
Map
map length,
(“Annie”, “Bob”, “Chandra”)
# map EXPR, LIST
# map BLOCK LIST
map { length } (…)
map length
[“Annie”, “Bob”, “Chandra”]
![Page 20: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/20.jpg)
Map
map length,
(“Annie”, “Bob”, “Chandra”)
# map EXPR, LIST
# map BLOCK LIST
map { length } (…)
# length EXPR
# length
# If EXPR is omitted, returns the length of $_
map length
[“Annie”, “Bob”, “Chandra”]
![Page 21: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/21.jpg)
Map
map length,
(“Annie”, “Bob”, “Chandra”)
• expression
• $_ (“it”)
• optional parameters
map length
[“Annie”, “Bob”, “Chandra”]
• function
• currying
• “lifting”
![Page 22: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/22.jpg)
Doubling
map $_ * 2, (1..5)
=> (2,4,6,8,10)
map (*2) [1..5]
=> [2,4,6,8,10]
![Page 23: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/23.jpg)
Doubling
map double($_), (1..5)
use experimental ‘signatures’;
sub double ($x) { $x * 2 }
map double [1..5]
double x = x * 2
-- or
double = (*2)
![Page 24: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/24.jpg)
Define our own ‘fmap’
fmap \&double, (1..5)
sub double ($x) { $x * 2 }
sub fmap ???
map double [1..5]
double x = x * 2
-- or
double = (*2)
![Page 25: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/25.jpg)
Define our own ‘fmap’
fmap \&double, (1..5)
sub double ($x) { $x * 2 }
sub fmap ($fn, @list) {
map $fn->($_), @list
}
map double [1..5]
double x = x * 2
-- or
double = (*2)
![Page 26: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/26.jpg)
Prototypes...
map _\&double, (1..5)
sub double ($x) { $x * 2 }
{
no experimental 'signatures';
sub _ ($) { shift->($_) }
}
map double [1..5]
double x = x * 2
-- or
double = (*2)
![Page 27: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/27.jpg)
Reverse...
??? map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
![Page 28: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/28.jpg)
Reverse...
map reverse,
(“foo”, “bar”)
=> ...
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
![Page 29: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/29.jpg)
Reverse...
map reverse,
(“foo”, “bar”)
=> () # wtf?
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
![Page 30: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/30.jpg)
Reverse...
map reverse,
(“foo”, “bar”)
=> ()
# reverse LIST
reverse (“foo”, “bar”)
=> (“bar”, “foo”)
reverse () => ()
# reverse STRING
reverse “foo” => “oof”
# reverse ($_)
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
![Page 31: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/31.jpg)
Reverse...
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
![Page 32: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/32.jpg)
Reverse...
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
• map is really concatMap!
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
![Page 33: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/33.jpg)
concatMap vs map
map {$_,$_} (1..3)
=> (1,1,2,2,3,3)
map (\x->[x,x]) [1..3]
=> [[1,1],[2,2],[3,3]]
![Page 34: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/34.jpg)
concatMap vs map
map {$_,$_} (1..3)
=> (1,1,2,2,3,3)
concatMap (\x->[x,x]) [1..3]
=> [1,1,2,2,3,3]
![Page 35: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/35.jpg)
Reverse with concatMap
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
concatMap reverse
[“foo”, “bar”]
=> [“oofrab”] -- eeek!
![Page 36: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/36.jpg)
Reverse with concatMap
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
• scalar vs list context
concatMap (return . reverse)
[“foo”, “bar”]
=> [“oof”, “rab”]
• map vs concatMap
• return (to wrap value in e.g. list)
![Page 37: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/37.jpg)
Length of lists of lists:
??? ([1,2,3], [5,4,3,2,1])
=> (3, 5)
![Page 38: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/38.jpg)
Length of LoL
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
![Page 39: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/39.jpg)
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map length, @l
=> (16, 16) # wtf
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
![Page 40: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/40.jpg)
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map length, @l
=> (16, 16)
# length STRING
[1,2,3] => “ARRAY(0x293a1d8)”
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
![Page 41: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/41.jpg)
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map length, @l
=> (16, 16)
# length STRING
[1,2,3] => “ARRAY(0x293a1d8)”
# scalar @array
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
![Page 42: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/42.jpg)
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map scalar, @l
=> ([1,2,3], [5,4,3,2,1])
# [1,2,3] is already scalar!
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
![Page 43: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/43.jpg)
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map scalar @$_, @l
=> (3, 5)
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
![Page 44: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/44.jpg)
Tails
??? map tail l
=> [[2,3], [4,3,2,1]]
![Page 45: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/45.jpg)
Tails
map [ @$_[1..$#$_] ], @l
=> ([2,3], [4,3,2,1])
map tail l
=> [[2,3], [4,3,2,1]]
![Page 46: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/46.jpg)
Tails
map [ @$_[1..$#$_] ], @l
=> ([2,3], [4,3,2,1])
• Yes, I know
map tail l
=> [[2,3], [4,3,2,1]]
![Page 47: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/47.jpg)
Tails
map tail($_), @l
=> () # bah!
sub tail ($head, @tail) {
@tail
}
map tail l
=> [[2,3], [4,3,2,1]]
![Page 48: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/48.jpg)
Tails
map __\&tail, @l
=> ([2,3], [4,3,2,1])
sub tail ($head, @tail) {
@tail
}
{
no experimental 'signatures';
sub _ ($) { shift->($_) }
sub __ ($) { [shift->(@$_)] }
}
map tail l
=> [[2,3], [4,3,2,1]]
![Page 49: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/49.jpg)
A thought...
Scalar/list context
Sigils ($, @, %)
implicit $_
Optional parameters
References and dereferencing
Automatic type coercions
Subroutine prototypes
Type system
![Page 50: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/50.jpg)
Example
Scalar/list context Monads (Maybe, List)
![Page 51: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/51.jpg)
Example:
-- https://prime.haskell.org/wiki/Libraries/Proposals/MonadFail
import qualified Data.Map as M
en2it = M.fromList [
("hello","ciao"),
("goodbye","ciao"),
("pasta","pasta") ]
translate db k =
let v = M.lookup k db
in case v of
Nothing -> fail "No translation"
Just v' -> return v'
![Page 52: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/52.jpg)
Example:
*Main> translate en2it "hello"
"ciao"
*Main> translate en2it "hello" :: Maybe String
Just "ciao"
*Main> translate en2it "hello" :: [String]
["ciao"]
*Main> translate en2it "whipuptitude"
*** Exception: user error (No translation)
*Main> translate en2it "whipuptitude" :: Maybe String
Nothing
*Main> translate en2it "whipuptitude" :: [String]
[]
![Page 53: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/53.jpg)
To be fair...
Perl:
• Larry Wall: linguist, missionary
• + jobbing programmers
• pragmatic
• magpie-like
Haskell:
• Decades of Comp Sci professors and PhD students
• purity
• experimentation
![Page 54: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/54.jpg)
Why are we* so terrified of types?
en2it :: M.Map [Char] [Char]
en2it = M.fromList [
("hello","ciao"),
("goodbye","ciao"),
("pasta","pasta") ]
translate :: (Monad m, Ord k) => M.Map k a -> k -> m a
translate db k =
let v = M.lookup k db
in case v of
Nothing -> fail "No translation"
Just v' -> return v'
![Page 55: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/55.jpg)
Why are we* so terrified of types?
en2it :: M.Map [Char] [Char]
en2it = M.fromList [
("hello","ciao"),
("goodbye","ciao"),
("pasta","pasta") ]
translate :: (Monad m, Ord k) => M.Map k a -> k -> m a
translate db k =
let v = M.lookup k db
in case v of
Nothing -> fail "No translation"
Just v' -> return v'
![Page 56: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/56.jpg)
Why are we* so terrified of types?
“Programming in ML is very pleasant. More than almost any other language I know, you can just write down the definitions of the functions as they come into your head. You don't need to bother with declarations; everything is just figured out for you automatically.
And you do get a lot of type errors, both actual failures and also places where the type emitted by the compiler is not what you thought it should be.
But unlike in C or Pascal, every one of those errors indicates a real, serious problem in your program, not merely something you have to groan over and try to work around the compiler's stupidity yet again.”
-- mjd http://perl.plover.com/classes/typing/notes.html
![Page 57: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/57.jpg)
Why are we* so terrified of types?
[4, 8, 15, 16, 23, 42] :: [Int]
![Page 58: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/58.jpg)
Type terror: undefined values
[4, 8, 15, undef, 16, 23, 42] :: [Panic!]
![Page 59: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/59.jpg)
Type terror: undefined values
my %en2it = (
hello => “ciao”,
goodbye => “ciao”,
pasta => “pasta”
);
my @l = map $en2it{$_},
(“hello", “monad", “pasta”);
my @c = grep defined, @l;
# (“ciao”, “pasta”)
![Page 60: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/60.jpg)
Type terror: undefined values
-- data Maybe a = Just a | Nothing
l = map (flip Map.lookup h)
[“hello", “monad", “pasta”]
-- [Just “ciao”, Nothing, Just “pasta”]
c = catMaybes l
-- [“ciao”, “pasta”]
![Page 61: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/61.jpg)
Type terror: signal values
[1, undef, 2, “X”, 3, -5]
# positive number: record
# undef: no record found
# “string”: processing instruction
# negative number: record flagged for deletion
![Page 62: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/62.jpg)
Type terror: signal values
records :: [Maybe Record]
records = [
Just Record (Left 1),
Nothing,
Just Record (Left 2),
Just Instruction “X”
Just Record (Left 2),
Just Record (Right 5)]
data Record =
Record (Either Int Int) | Instruction String
![Page 63: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/63.jpg)
Type terror: but! but! but!
serialization (show)
objects of a particular class (typeclasses)
GADTs
existential types
dynamic introspection
...
![Page 64: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/64.jpg)
Bonus section #1practical oneliners
![Page 65: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/65.jpg)
april.txt
There is shadow under this red rock,
(Come in under the shadow of this red rock),
And I will show you something different from either
Your shadow at morning striding behind you
Or your shadow at evening rising to meet you;
I will show you fear in a handful of dust.
![Page 66: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/66.jpg)
Grep for a string
$ perl -ne ‘print if /shadow/’ < april.txt
???
![Page 67: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/67.jpg)
Grep for a string
$ perl -ne ‘print if /shadow/’ < april.txt
notaoneliner.hs:
import Data.List
main = interact (
unlines .
(filter (\a -> "shadow" `isInfixOf` a))
. lines )
$ runghc notaoneliner.hs < april.txt
![Page 68: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/68.jpg)
april.txt | grep shadow
There is shadow under this red rock,
(Come in under the shadow of this red rock),
Your shadow at morning striding behind you
Or your shadow at evening rising to meet you;
![Page 69: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/69.jpg)
Grep for a string
$ perl -ne ‘print if /shadow/’ < april.txt
hask.bash:
if which ghc > /dev/null
then
function h { ghc -e "interact ($*)" Ust.hs ; }
function hl { h "bylines ($*)" ; }
function hw { h "bywords ($*)" ; }
fi
$ hl ‘filter (regexBool “shadow”)’ < april.txt
![Page 70: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/70.jpg)
Ust.hs
https://wiki.haskell.org/Simple_Unix_tools
https://ulissesaraujo.wordpress.com/tag/command/
{-# LANGUAGE NoMonomorphismRestriction #-}
module Ust(
bylines, bywords, showln, regexBool, uniq, rpt, take', drop', head', tail', tail10, tac, rev, rev_w, wc_c, wc_l, wc_w, space, unspace, remove, upper, clean, clean', clean'', blank, join, tr, tr_d, grep, grep_v, cksum
) where
import Control.Monad.Instances; import Data.List; import Data.Char; import Data.Maybe; import Text.Printf; import System.Environment; import Text.Regex.Posix
-- First, three helpers
bylines f = (unlines . f . lines)
bywords f = (unwords . f . words)
showln = (++ "\n") . show
-- simple boolean regex matching
regexBool r l = l =~ r :: Bool
...
![Page 71: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/71.jpg)
Uppercase
$ perl -pe ‘$_ = uc’ < april.txt
$ h upper < april.txt
Ust.hs:
upper = map toUpper
![Page 72: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/72.jpg)
april.txt | upper
THERE IS SHADOW UNDER THIS RED ROCK,
(COME IN UNDER THE SHADOW OF THIS RED ROCK),
AND I WILL SHOW YOU SOMETHING DIFFERENT FROM EITHER
YOUR SHADOW AT MORNING STRIDING BEHIND YOU
OR YOUR SHADOW AT EVENING RISING TO MEET YOU;
I WILL SHOW YOU FEAR IN A HANDFUL OF DUST.
![Page 73: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/73.jpg)
Sort
$ perl -e 'print sort <>' < april.txt
$ hl sort < april.txt
![Page 74: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/74.jpg)
april.txt | sort
(Come in under the shadow of this red rock),
And I will show you something different from either
I will show you fear in a handful of dust.
Or your shadow at evening rising to meet you;
There is shadow under this red rock,
Your shadow at morning striding behind you
![Page 75: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/75.jpg)
Sorted words
$ perl -e 'print join " ",
sort map { chomp; split } <>' < april.txt
$ hw sort < april.txt
![Page 76: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/76.jpg)
april.txt | sort-words
(Come And I I Or There Your a at at behind different dust. either evening fear from handful in in is meet morning of of red red rising rock), rock, shadow shadow shadow shadow show show something striding the this this to under under will will you you you you; your
![Page 77: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/77.jpg)
Bonus section #2real world(ish) code
![Page 78: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/78.jpg)
Modelling TV programmes
Brand:“Have I Got News For You?”
Series:“3”
Episode:“1” /
HIGNFY123
![Page 79: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/79.jpg)
Modelling TV programmes
Brand:“Have I Got News For You?”
Series:“3”
Episode:“1” /
HIGNFY123
Brand:“Have I Got OLD News For You?”
Series:“1”
Episode:“5” /
HIGNFY123
![Page 80: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/80.jpg)
Data modelling
package Programme;
use Moo;
use Types::Standard
qw/ Maybe Str /;
has id => ( is => 'ro',
isa => Maybe[Str] );
has id2 => ( is => 'ro',
isa => Maybe[Str] );
package Brand;
use Moo;
extends 'Programme';
# ditto Series, Episode...
type PrimaryId = Maybe String
type AlternateId = Maybe String
data Prog = Prog
ProgType
PrimaryId AlternateId
deriving (Eq, Ord, Show)
data ProgType =
Brand |
Series |
Episode
deriving (Eq, Ord, Show)
![Page 81: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/81.jpg)
The “Database”package Database;
use Moo;
use Types::Standard
qw/ArrayRef HashRef InstanceOf/;
has list => (
is => 'ro',
isa => ArrayRef[InstanceOf["Programme"]],
...
);
has graph => (
is => 'ro',
isa => HashRef[InstanceOf["Programme"]],
...
);
data Database = Database {
list :: [Prog],
graph :: M.Map Prog Prog
}
![Page 82: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/82.jpg)
Get Hierarchyuse experimental ‘signatures’;
sub getHierarchy($self, $prog) {
if (my $parent = $self->lookup($prog->id)) {
return ($prog, $self->getHierarchy($parent))
}
else { return $prog }
}
getHierarchy :: Database -> Prog -> [Prog]
getHierarchy db p =
let l = M.lookup p (graph db)
in case l of
Nothing -> [p]
Just (parent) -> p : (getHierarchy db parent)
![Page 83: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/83.jpg)
Get Hierarchyuse experimental ‘signatures’;
use MooX::HandlesVia;
has graph => (
is => 'ro',
isa => HashRef[InstanceOf["Programme"]],
handles_via => 'Hash',
handles => { lookup => ‘get’ }
);
sub getHierarchy($self, $prog) {
if (my $parent = $self->lookup($prog->id)) {
return ($prog, $self->getHierarchy($parent))
}
else { return $prog }
}
![Page 84: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/84.jpg)
Search for a programmesub search ($self, $prog1) {
my sub match ($prog2) {
return unless ref $prog1 eq ref $prog2;
return unless $prog1->id or $prog1->id2;
return unless $prog2->id or $prog2->id2;
return unless $prog1->id or $prog2->id2;
return unless $prog1->id2 or $prog2->id;
return if $prog1->id and $prog2->id and $prog1->id ne $prog2->id;
return if $prog1->id2 and $prog2->id2 and $prog1->id2 ne $prog2->id2;
return 1;
}
return $self->filter(\&match);
}
![Page 85: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/85.jpg)
Search for a programmeuse experimental 'lexical_subs';
has list => (
is => 'ro',
isa => ArrayRef[InstanceOf["Programme"]],
handles_via => 'Array',
handles => { filter => 'grep'}
);
![Page 86: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/86.jpg)
Search for a programmesearch db p =
filter (match p) (list db)
where
match (Prog t1 _ _) (Prog t2 _ _) | t1 /= t2 = False
match (Prog _ Nothing Nothing) _ = False
match _ (Prog _ Nothing Nothing) = False
match (Prog _ Nothing _) (Prog _ _ Nothing) = False
match (Prog _ _ Nothing) (Prog _ Nothing _) = False
match (Prog _ (Just p1) _) (Prog _ (Just p2) _) | p1 /= p2 = False
match (Prog _ _ (Just a1)) (Prog _ _ (Just a2)) | a1 /= a2 = False
match _ _ = True
![Page 87: Is Haskell an acceptable Perl?](https://reader033.vdocuments.us/reader033/viewer/2022052318/58f3066a1a28abb52d8b45f3/html5/thumbnails/87.jpg)
Thanks!@osfameron
https://github.com/osfameron/haskell-perl