The main package manager to use in Haskell is Cabal. Make sure that the Cabal version that you are using is at
least 3.0. Then build
, repl
, install
, etc will use the upgraded v2-style versions that work with minimal problems.
Documentation
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE MonoLocalBinds #-} | |
{-# LANGUAGE TypeApplications #-} | |
{-# LANGUAGE TypeOperators #-} | |
module Main where | |
import Control.Monad.Except | |
import Control.Monad.Identity | |
import Data.Bifunctor |
pub trait Unplug { | |
type Gen; | |
type A; | |
} | |
pub trait Plug<A> { | |
type Out: Unplug<A = A>; | |
} | |
pub trait Functor: Unplug + Plug<<Self as Unplug>::A> { |
There are a few ways of reaching into records that each have their own advantages and drawbacks. I keep reevaluating these methods every time I want to reach into a record so I'm writing down the cons for each method so I can remember them later. Most of these methods will be in the context of storing multiple effects, because that is the most common reason for me to want to reach into a record without caring about the record type.
The simplest way of reaching into a record is to use a Has*** typeclass. For example if I have an effectful
record of functions UserRepo m
, then a typeclass to reach into an arbitrary record and pull out a UserRepo m
would
{-# LANGUAGE FunctionalDependencies #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE RecordWildCards #-} | |
{-# LANGUAGE TemplateHaskell #-} | |
module Main where | |
import Control.Lens | |
import Control.Monad.State | |
import Data.IORef |
cmake_minimum_required(VERSION 3.12) | |
project(Test) | |
add_executable(TestExe main.cpp) | |
target_compile_options(TestExe PRIVATE -Wall -Werror -Wno-missing-braces -g) | |
set_target_properties(TestExe PROPERTIES CXX_STANDARD 17) |
{-# LANGUAGE BangPatterns #-} | |
{-# LANGUAGE GADTs #-} | |
module ReverseInt where | |
import Data.Foldable | |
data MyNum a where | |
MyNum :: (Num a, Integral a) => a -> MyNum a | |
instance Foldable MyNum where |
Its common to refer to Haskell's typeclasses as a more powerful version of traits in other languages. However, because Haskell is pure and keeps track of effects in the type system, certain traits in other languages can't be modeled as easily with typeclasses. For example, in Rust you can write a trait describing a store that performs side effects:
pub trait Store<K, V> {
fn get(&self, key: K) -> Option<V>;
fn set(&mut self, key: K, value: V);
{-# LANGUAGE UndecidableInstances #-} | |
module Main where | |
-- Warning: do not do this in real Haskell code! | |
-- It's way simpler to just refactor your code instead of | |
-- going through hoops to try to avoid "breaking" changes. | |
import Control.Lens | |
import Data.Generics.Sum |