3 ms·
I'm approaching an intermediate level in Haskell, but I don't really see how writing a program in Haskell is any more like writing a language than writing a pro
by treebog 9y ago
I'm approaching an intermediate level in Haskell, but I don't really see how writing a program in Haskell is any more like writing a language than writing a program in, say, python. Could you elaborate or point to some DSLs written on top of Haskell? I'm very curious.
- louthy 9y agoHow about BASIC in Haskell? http://augustss.blogspot.co.uk/search/label/BASIC http://augustss.blogspot.co.uk/search/label/BASIC
- Sunset 9y agoEveryday we stray further from god's light
- wruza 9y ago(From article comments) #include <stdio.h> int main(int argc, char **argv) { double i, s; s = 0; for (i = 1; i < 100000000; i++) s += 1/i; printf("Almost infinity is %g\n", s); } Lennarts-Computer% gcc -O3 inf.c -o inf Lennarts-Computer% time ./inf Almost infinity is 18.9979 1.585u 0.009s 0:01.62 97.5% 0+0k 0+0io 0pf+0w And now the Haskell code: import BASIC main = runBASIC' $ do 10 LET I =: 1 20 LET S =: 0 30 LET S =: S + 1/I 40 LET I =: I + 1 50 IF I <> 100000000 THEN 30 60 PRINT "Almost infinity is" 70 PRINT S 80 END And running it: Lennarts-Computer% ghc --make Main.hs [4 of 4] Compiling Main ( Main.hs, Main.o ) Linking Main ... Lennarts-Computer% ./Main Almost infinity is 18.9979 CPU time: 1.57s As you can see it's about the same time. In fact the assembly code for the loops look pretty much the same. Here's the Haskell one: LBB1_1: ## _L4 movsd LCPI1_0, %xmm2 movapd %xmm1, %xmm3 addsd %xmm2, %xmm3 ucomisd LCPI1_1, %xmm3 divsd %xmm1, %xmm2 addsd %xmm2, %xmm0 movapd %xmm3, %xmm1 jne LBB1_1 ## _L4 --- OMG that is astonishing
- matthew_leon 9y agoHere is a fantastic article to get you started down this path. Note that the author, in his introduction, submits that the approach to FizzBuzz in this paper is a "somewhat tongue-in-cheek solution." Nevertheless, by applying this kind of thinking to what is, in some ways, a deceptively simple-looking problem, the paper serves as a great starting point for using DSLs as an approach to problem-solving. https://themonadreader.files.wordpress.com/2014/04/fizzbuzz.pdf https://themonadreader.files.wordpress.com/2014/04/fizzbuzz....
- WmyEE0UsWAwC2i 9y agoYou can think a monad defines a DSL. Let's take for example the Rand[0] monad: type Rand g = RandT g Identity newtype RandT g m a = ... -- with runRandT :: (Monad m, RandomGen g) => RandT g m a -> g -> m (a, g) newtype MyType = Rand StdGen -- now you can define intGreaterThan :: Integer -> MyType Integer intGreaterThan = ... randomName :: Integer -> MyType String randomName length = ... -- an finally convine the two above nRandomNames :: Integer -> Integer -> MyType [String] nRandomNames length n | n <=0 = return [] | otherwise = do tailNames <- nRandomNames (n-1) headName <- randomName length return (headName:tailNames) These functions of type `...->MyType a` can be viewed as a DSL where the Random generator state is abstracted away. [0]hackage.haskell.org/package/MonadRandom-0.3/docs/Control-Monad-Random.html
- KirinDave 9y agoThere is another article about FizzBuzz I wrote roughly 5 years ago (forgive the pronouns, I need to rebuild the site and I'm procrastinating on the css). http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html This uses a slightly different set of abstractions with the same problem. But perhaps more specifically, when you select a monad stack (group of effects) to compose to solve a problem you're building the features of the language and its effects. And if you use the "final tagless" or "Free" approaches you're doing that even more directly.