If you want to use Haskell for anything more than just trying something out for a few minutes, installing ghc is definitely the best way, which includes ghci, regardless of whether you install it on Linux or on Windows. The most popular way to do that these days is by installing stack, which manages the versions of ghc as well as of specific haskell packages.
However, if you just want to quickly try out something, I think the website repl.it is pretty good - it also includes a ghci prompt.
This has to do with monomorphism (or lack thereof). Look at this alternate transcript:
GHCi, version 7.10.1: http://www.haskell.org/ghc/ :? for help Prelude> :set +t Prelude> let x = 1 + 2 x :: Num a => a Prelude> :sp x x = _ Prelude> x 3 it :: Num a => a Prelude> :sp x x = _ Prelude> let y = 1 + 2 :: Int y :: Int Prelude> :sp y y = _ Prelude> y 3 it :: Int Prelude> :sp y y = 3
> Or is List just implementing Functors fmap by then simply aliasing to its own old-school map function and these were kept separate to avoid certain confusions when fmap landed?
List's map
and fmap
are the exact same function. For a short period, map's signature was actually generalized to be the same as fmap:
> What happened was that the type of map was generalized to cover Functor in Haskell 1.3. I.e., in Haskell 1.3 fmap was called map. This change was then reverted in Haskell 1.4 and fmap was introduced. The reason for this change was pedagogical; when teaching Haskell to beginners the very general type of map made error messages more difficult to understand. In my opinion this wasn't the right way to solve the problem. -- Lennart Augustsson
I'm not certain. The Core is very similar for each version, with the main difference apparently being where the recursion is introduced. Anyone who can read Core better than I can have some insight? The Occ=LoopBreaker stands out to me, but I don't remember if that's significant, really.
The world representation is not good: the Cell
list makes it difficult and very inefficient to do things.
The idiomatic way to approach this in Haskell would be to use a two-dimensional array for the world (probably an unboxed array of Bool
, if you don't want to store any fancier state). This should simplify your code, once you get the hang of working with arrays.
The first line is supposed to import the module, not define it (probably a typo on the author's part):
import Data.Char
^(Full code in interactive repl)
Haskell wikibook has a chapter about syntax around modules if you want to read more.
Why do you ask us when you could try it for yourself?
$ ghci GHCi, version 7.10.1: http://www.haskell.org/ghc/ :? for help Prelude> data Tile = Empty | One | Two | Three | Four | Five | Six | Seven | Eight | Nine deriving (Show, Eq, Enum) Prelude> fromEnum Six 6
You're looking at the docs for the libraries that come with ghc 7.8, but you are running an earlier version of ghc, where this instance is not yet included.
Important question: can we have a privileged Self
type to denote ourselves?
If not, I'm not sure what you're asking for. If an Action
depends on user input, we have to allow for the possibility that the user may give invalid input. (And likely your UI will want to know this so it can give a red X when you try to shoot your character, for example.) That requires having a Maybe
or something morally equivalent at some point.
If you figure out how to prevent unwanted user input at compile time, you'll be the world's first trillionaire.
But if we can have a privileged Self
, maybe the client in a multiplayer game, would something like this work?
https://repl.it/repls/SlatebluePreciousGlobalarrays
data EntityData = EData { hp :: Int , shouting :: String } deriving Show
class IsSelf e where shout :: e d -> String -> e d
class IsEntity e where heal :: e d -> e d
class IsOther e where shoot :: e d -> e d
data Self k = Self EntityData k deriving Show instance IsSelf Self where shout (Self d k) s = Self ( d { shouting = s } ) k instance IsEntity Self where heal (Self d k) = Self ( d { hp = 100 } ) k
data Other k = Other EntityData k deriving Show instance IsOther Other where shoot (Other d k) = Other ( d { hp = (hp d - 10) } ) k instance IsEntity Other where heal (Other d k) = Other (d { hp = 100 } ) k
I'm rather embarrassed because I can't get rid of the dummy type variable k
. Just imagine it's name :: String
or something, idk, it's not important.
I suspect that if we tried really hard we could make heal
generic without making everything terribly complex, such that we could go instance IsEntity Self where heal = _heal
without making shit weird.
I imagine our resident type hackers could blow this out of the water!
Looks like some extra bookkeeping (which I absolutely can't read) at the top of each function, and an extraneous case is optimized out of both V1 and V2.
You may be interested in Elm (http://elm-lang.org/). It's sort of like Haskell-lite specifically tailored to web development. I've found it incredibly easy to be super productive in compared to most front end stacks.
I think LYAHFGG gives a fun, free, and fast "taste" of Haskell, if you just want to try it out. If you want to actually commit to learning it, I second the recommendation of https://haskellbook.com as it:
The only downsides are that it isn't free (though it is very reasonably priced) and it is very long (~1200 pages). Don't let either of those obstacles stop you, though.
PS, https://www.amazon.com/Get-Programming-Haskell-Will-Kurt/dp/1617293768 seems a bit less monumental in size, a little more focused on "let's make some programs" than "let's understand every nuance." It seems to have some positive reviews though I haven't read it entirely. If HPFFP is too intimidating (again, I don't think it should be, but YMMV) then I'd suggest you take a look at GPWH.
Have you installed the XCode command line tools? A lot of the utilities necessary to run a developer environment on the Mac (including <code>ar</code>) are not installed by default.
Try running xcode-select --install
from the command line.
I copied Main.hs
into a file MainVec.hs
where I wrote all of my changes.
I then ran
diff -u Main.hs MainVec.hs > vec.patch
To compute the difference and then store it into the file Vec.patch
.
If you leave out the > vec.patch
, it will just print the difference to the display.
The -u
flag is there so that the diff is more easily read by humans.
If you don't intend people to actually read it, then diff Main.hs MainVec.hs
would display
4a5 > import qualified Data.Vector as V 29c30 < type Program = [Command] --- > type Program = V.Vector Command 60c61 < in program --- > in V.fromList program 62c63 < assemble :: String -> Program --- > assemble :: String -> [Command] 74c75 < annotateBwd :: [Int] -> [(Int, Command)] -> Program --- > annotateBwd :: [Int] -> [(Int, Command)] -> [Command] 85c86 < annotateFwd :: [Int] -> [(Int, Command)] -> Program --- > annotateFwd :: [Int] -> [(Int, Command)] -> [Command] 98c99 < | iptr ctx >= length prg = return () --- > | iptr ctx >= V.length prg = return () 100c101 < ctx' <- run ctx $ prg !! iptr ctx --- > ctx' <- run ctx $ prg V.! iptr ctx
I also checked the diff to make sure that only the intended changes were listed. I had to delete an extra newline that I accidentally introduced while experimenting.
You may also be interested in <code>git diff</code>, for if your changes are made to a git repo, I avoided it because this was a 2 file experiment.
Likewise, git
(and other version control) supports email workflows, which can be adapted to other text chat systems.
Thank you for taking the time! I should make an effort to provide the full context.
I think your assumptions are correct except for one detail¹. The goal of the parser is to count the number of atoms in a molecule only. Over
is indeed the closing of a scope, to account for cases like "Mg(OH)2"
where in this case we have 1 Mg, 2 O and 2 H atoms, "OH"
being a scope where every atom is doubled, ")2"
creating a Mult 2
. Interestingly enough, Over
comes from the opening bracket token as ¹at this point I'm parsing the formula backwards.
What is confusing me here is the way I'm handling the nodes and rests recursively at the end. I understand there's a need to "look at more than one lexeme in the future" but I get lost.
~~I have just woken up but I'll post a link to the full code!~~ Here's the full parser
Note: This was the first parser I ever wrote, the terminology might not be accurate (token, lexer, lexeme, ...) as I was more interested in solving this particular problem by myself than in studying the canonical way to build a parser. If you find some term out of place feel more than welcome to correct me!
>I concede that it could be a good starting point to focus on the bare minimum and then develop from there.
My path began with the two courses from Computer Science Center on Stepik (it's 100% in Russian), and I think they did a great job. It gave me the bare minimum of knowledge and confidence to continue to develop on my own. I doubt that the certificates I got worth anything, but it doesn't matter at all.
it's important to make your introduction to the language systematic with the guidance of someone expirienced, who knows what's important, opposed to a chaotic newcomer's Brownian motion, when you have no idea what feature of the language to study, why, how, what are the benifits, e.t.c. You need to obtain atleast somewhat holistic view at the language, before you can make your own steps.
P.S. I hope I don't have to say how important the exercises are.
At that point, may as well go full tilt and use types to enforce a consistent use of the modulus: modular-arithmetic. (see also: this).
One further question for /u/nolrai, /u/merijnv, /u/rule and others. In another part of my code I tried to construct a lookup table by wrapping a vector generator in a function here's the basic construction of how I did that: https://repl.it/repls/ChocolateAshamedDebugger
From what I can tell this actually calls generate every time I call the curried function. Am I right about that? What is the right way to construct this? Can it be done as a pure function?
nth _ [] = error "nth: empty list" nth 0 (x:) = x nth n (:xs) = nth (n - 1) xs
is how I would write it. You seem to want to use if
, which is okay, but it misses the value / type refinement that case
analysis or pattern-matching does. Your way might look like:
nth k l = if k == 1 then head l else nth (k - 1) (tail l)
both work in my GHCi, and give the expected results. Mine starts indexing at 0, so nth 3 [1.4.5.9.8]
gives 9
as I expect, but yours indexes from 1, so nth 3 [1,4,5,9,8]
gives 5
as you expect.
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help Prelude> :{ Prelude| nth _ [] = error "nth: empty list" Prelude| nth 0 (x:) = x Prelude| nth n (:xs) = nth (n - 1) xs Prelude| :} Prelude> nth 3 [1,4,5,9,8] 9 Prelude> nth k l = if k == 1 then head l else nth (k - 1) (tail l) Prelude> nth 3 [1,4,5,9,8] 5
Ah, I'm on the last GHC version where MonomorphismRestriction
is on by default:
$ ghci sprint.hs GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Main ( sprint.hs, interpreted ) Ok, one module loaded. *Main> :t t1 t1 :: [Integer]
GHCi, version 8.4.1: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/me/.ghci Prelude λ data greet = Hello a | By b
<interactive>:1:6: error: Malformed head of type or class declaration: greet Prelude λ data Greet = Hello a | By b
<interactive>:2:20: error: Not in scope: type variable ‘a’
<interactive>:2:27: error: Not in scope: type variable ‘b’ Prelude λ
I did it:
> Developers-MBP:chapter6 developer$ stack upgrade > Current Stack version: 1.3.2, available download version: 1.4.0 > Newer version detected, downloading > Querying for archive location for platform: osx-x86_64-static > Querying for archive location for platform: osx-x86_64 > Downloading from: https://github.com/commercialhaskell/stack/releases/download/v1.4.0/stack-1.4.0-osx- x86_64.tar.gz > Download complete, testing executable > Version 1.4.0, Git revision e714f1dd3fade19496d91bd6a017e435a96a6bcd (4640 commits) x86_64 hpack-0.17.0 > New stack executable available at /Users/developer/.local/bin/stack
So when I start:
> Developers-MacBook-Pro:~ developer$ stack ghci > Configuring GHCi with the following packages: > GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help > Loaded GHCi configuration from /private/var/folders/2x/t_2cl03x2092dkzvc702d7lc0000gn/T/ghci1718/ghci-script
is still version 8.0.1 why?
The latest version of GHC 8 the extension <code>TypeApplications</code> gives you syntax to apply terms to types term @MyType
(this is what term (Proxy :: Proxy MyType)
emulates):
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help >>> :set -XAllowAmbiguousTypes >>> :set -XTypeApplications >>> :set -XScopedTypeVariables >>> class Foo a where fooMin :: Int >>> data MyValue >>> instance Foo MyValue where fooMin = 10 >>> instance Foo Char where fooMin = 2020
This allows you to define a function
useMin :: forall a b. (Foo a, Foo b) => Int useMin = fooMin @a + fooMin @b
>>> useMin @MyValue @MyValue 20 >>> useMin @Char @MyValue 2030 >>> useMin @Char @Char 4040
When I did it I got a warning "Warning: Literal 34234754358987623232 is out of the Int range -9223372036854775808..9223372036854775807"
So your input number is getting wrapped around to (presumably, I didn't check) a negative.
EDIT: Alright I've convinced myself this is a bug on ghc(i). This is a complete ghci session.
$ ghci tmp.hs GHCi, version 7.8.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( tmp.hs, interpreted ) Ok, modules loaded: Main. *Main> let test = [1] :: Integral a => [a] *Main> let test2 = take 1 (basedigits 58 34234754358987623232) *Main> :t test test :: Integral a => [a] *Main> print test [1] *Main> :t test2 test2 :: Integral a => [a] *Main> print test2 [1] *Main> map ([0..] !!) test [1] *Main> map ([0..] !!) test2 [<interactive>: out of memory (requested 2097152 bytes)
EDIT: explained above as not a bug.
There are quite a few ways to implement Fibonacci sequence in Haskell. This page has some of them: http://www.haskell.org/haskellwiki/The_Fibonacci_sequence
Have you had a look at resources such as Learn You a Haskell? It will teach you how to understand the Naive Definition and Tail Recursive (2.1.1) from the wiki page, at the least. It will also teach you basic I/O.
Thanks again. I made some more experiments based on the better understanding I now have; they are also in the repl.it page. I think I found two viable solutions.
r
will be unified with some type:
class HasBuilderParam w p b | p -> b where
toBuilderParam :: p -> Builder w r (b -> r)
default toBuilderParam
:: ( HasBuilder w p
, AppendParameters w p r ~ (b -> r)
)
=> p -> Builder w r (b -> r)
toBuilderParam = toBuilder
newtype Builder w r a = MkBuilder {runBuilder :: (w -> r) -> a }
class HasBuilder w a where
type AppendParameters w a r
type AppendParameters w a r = r
toBuilder :: a -> Builder w r (AppendParameters w a r)
~
Aahhh... you mean "the exact number... in which the overflow occurs", not "the exact number.. of the fibonacci number". I like the challenge, here you have:
https://repl.it/@crul/Fibonacci-Overflow-Test
It has not been trivial for me and I'm pretty sure it can be done better. Feel free to point out errors and improvements, thanks! :)
I've started to learn a few days ago, so not 100% sure this is the right way, but looking at this stackoverflow answer I came up with this:
fastFib :: Int -> Int -> Int -> Int fastFib val prev counter = if counter == 0 then prev else fastFib (val + prev) val (counter - 1)
*Main> fastFib 1 1 1000 9079565065540428013
On repl.it: https://repl.it/@crul/Fast-Fibonacci
You can write:
https://repl.it/repls/ConstantLastingAttribute
allSame :: [String] -> [String] allSame list = let maxLength = maximum . map length $ list in map (pad maxLength) list
pad :: Int -> String -> String pad len string = take len $ string ++ repeat '+'
main = putStrLn . show . allSame $ ["computer", "maus"]
I started with Get Programming with Haskell by Will Kurt and thought it was fantastic. If you're a bit more advanced you may prefer Practical Haskell by Alejandro Serrano Mena.
The "spider web" is because the background is transparent.
To set an actual background color instead of transparent, use bg
:
> To "set the background color" of a diagram, use the bg function—which does not actually set any attributes, but simply superimposes the diagram on top of a bounding rectangle of the given color. The bgFrame function is similar but the background is expanded to frame the diagram by a specified amount.
(Taken from http://projects.haskell.org/diagrams/doc/manual.html#texture. It's at the very end of the "Color and Opacity" section, just before "Linear Gradients".)
Post a tio.run link if you want people to debug your code for you:
Remove root :: Tree Int
; that's only valid at top level, not inside a function definition
Use let root = Leaf 2 :: Tree Int
if you want to declare the type inside a function.
Not sure what you mean, you can still partially apply: Try it online!
I'd use a where clause too since I'm quite used to it, but I was focusing on the reading flow which it wouldn't preserve. Not sure what you mean by not being valid Haskell - it sure is just not very commonly used.
The second paragraph of the documentation for <code>Show</code> says
> Minimal complete definition: showsPrec
or show
.
Which means if you implement Show
manually, you must provide definitions for at least one of showsPrec
and show
. (The default definitions are defined in terms of each other.)
Usually you don't want to manually implement Show
: the compiler will implement Show
for you if you say deriving Show
, as Lurker378 points out.
Starting with ghc 7.8.1, the compiler will give you a warning if you miss out a required definition like this.
Also, for this
-- Workaround for argP <|> argP producing the wrong value. (<||>) :: ArgP r -> ArgP r -> ArgP r a <||> b = do al <- get case runArgT a al of Just (Nothing,_) -> b Just (Just x, al') -> put al' >> return (Just x) Nothing -> b
you want to make an instance of this: http://www.haskell.org/haskellwiki/Typeclassopedia#Other_monoidal_classes:_Alternative.2C_MonadPlus.2C_ArrowPlus
and not make your own operator
Yep, you are correct, that is better. Thanks for following up with that when you didn't have to.
Can you recommend any material I should go through to up my game? I recently finished Get Programming with Haskell and liked it. I know there others like Haskell from First Principles but I'm concerned it's outdated.
I would pick up this book <strong>https://www.amazon.com/Discrete-Mathematics-Using-Computer-ODonnell/dp/1846282411/ref=sr_1_1?ie=UTF8&qid=1548851126&sr=8-1&keywords=Discrete+Mathematics+Using+a+Computer</strong>.
I am wondering, if it is going to help me or not.