↑ This. Haskell makes it super easy to get good CLI filters. All you need to do is interact and process the string it gives you. You’ll automatically get streaming behavior because of laziness without lifting a finger.
interact is (String → String) → IO (), a function that takes a String → String (a function that takes a string and returns a string) and returns an I/O operation (which is a separate type since Haskell doesn’t have side-effects). The function you give it will receive all of stdin as a string and its output will be stdout. The magic comes because Haskell uses cons-lists that are lazy in their spine — the list doesn’t actually exist until you look at it. This means that, from your perspective (probably not how this is actually implemented), the list you return is iterated character-by-character, and each character that gets printed only waits for the characters it needs, allowing the rest of the stdin list to remain unevaluated.
↑ This. Haskell makes it super easy to get good CLI filters. All you need to do is
interact
and process the string it gives you. You’ll automatically get streaming behavior because of laziness without lifting a finger.Huh. My brain is on fire right now.
interact
is(String → String) → IO ()
, a function that takes aString → String
(a function that takes a string and returns a string) and returns an I/O operation (which is a separate type since Haskell doesn’t have side-effects). The function you give it will receive all of stdin as a string and its output will be stdout. The magic comes because Haskell uses cons-lists that are lazy in their spine — the list doesn’t actually exist until you look at it. This means that, from your perspective (probably not how this is actually implemented), the list you return is iterated character-by-character, and each character that gets printed only waits for the characters it needs, allowing the rest of the stdin list to remain unevaluated.Huh. My brain is on fire right now.