Hello all,
Don Stewart seems to have abandon plugins and has not (as far as I know)
responded to any recent inquiries about it. It needs a few patches to build
under GHC 7.0 and 7.4.
Since there has been no response for several months, I intend to usurp the
project and upload a new version to hackage in a few days, unless I hear
any strong objections.
My repository lives here at the moment:
http://src.seereason.com/plugins/
I will likely migrate it to patch-tag. However, patch-tag only supports
darcs 2 format, and plugins is darcs 1 format. There is no way to share
patches between darcs 1 and darcs 2 repos -- so I am not going to make the
change quite yet.
- jeremy
Hi Haskellers,
I propose to add a new function, traverseWithKey, to Data.Map:
"""
-- | /O(n)/.
-- @'traverseWithKey' f s == 'fmap' 'fromList' ('traverse' (\(k, v) ->
fmap ((,) k) (f k v)) ('toList' s))@
-- That is, behaves exactly like a regular 'traverse' except that the traversing
-- function also has access to the key associated with a value.
--
-- > traverseWithKey (\k v -> if k + v < 10 then Just (v + 1) else
Nothing) (fromList [(1, 2), (5, 4)]) == Just (fromList [(1, 3), (5,
5)])
-- > traverseWithKey (\k v -> if k + v < 10 then Just (v + 1) else
Nothing) (fromList [(5, 5)]) == Nothing
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)
"""
This is a rather useful function, and if we define it in SATed style
and with an INLINE pragma (as in my attached patch), GHC can generate
really good code for it at use sites.
While the utility of a traversal function like this is clear, we can
also use it to define other useful combinators such as
mapWithKeyM/mapMWithKey.
It can also be used to define efficient right/left with-key-folds on
Map that avoid a problem in GHC's strictness analyser. For example,
this function:
"""
c m = M.foldlWithKey (\k v (a, b) -> if k + v > 2 then (a, b) else (b,
a)) (0, 1) m
"""
Generates a loop which allocates a new pair on every iteration. (The
situation is the same with foldrWithKey.). If we have traverseWithKey,
we can work around it by defining an optimised fold for accumulators
that are pairs:
"""
newtype State2L s1 s2 a = State2L { unState2L :: s1 -> s2 -> (s1, s2) }
instance Functor (State2L s1 s2) where
fmap _ = State2L . unState2L
instance Applicative (State2L s1 s2) where
pure _ = State2L (,)
mf <*> mx = State2L $ \s1 s2 -> case unState2L mf s1 s2 of (s1,
s2) -> unState2L mx s1 s2 -- NB: left side first
{-# INLINE foldl2WithKey' #-}
foldl2WithKey' :: ((a1, a2) -> k -> v -> (a1, a2)) -> (a1, a2) ->
M.Map k v -> (a1, a2)
foldl2WithKey' f (a1, a2) kvs = unState2L (traverseWithKey (\k v ->
State2L $ \a1 a2 -> f (a1, a2) k v) kvs) a1 a2
"""
The loop resulting from foldl2WithKey' does not allocate any pairs
when compiled with current GHCs.
Of course, traverseWithKey is also sufficiently general that it can
implement many functions already exported from Data.Map (with varying
degrees of efficiency), such as find{Max,Min}, mapWithKey,
fold{r,l}WithKey, withAccumWithKey and mapAccumL.
There is precedence for the "traverseWithKey" name:
1. "unordered-containers" has a function with exactly this name and
compatible type, used for HashMaps [1]
2. The "keys" package defines a type class TraversableWithKey with a
compatible type [2]
This is an API addition so breakage from the change should be low.
Overall this should be a low risk addition to the interface which adds
a lot of flexibility. What do you think?
Deadline: 2 weeks (i.e. 28th March)
Patch is attached, assuming it doesn't get stripped by the mailing list manager.
Cheers,
Max
[1] http://hackage.haskell.org/packages/archive/unordered-containers/0.1.1.0/do…
[2] http://hackage.haskell.org/packages/archive/keys/0.1.0/doc/html/src/Data-Ke…
It's just been brought to my attention that there's a small bug in the
Network.URI code I wrote many years ago. I'll happily fix this, but I'm not
sure what are the current mechanisms for accessing/updating the library
repositories these days. Can anyone offer a pointer?
(I've checked the error report against RFC 3986, and confirm that the proposed
change seems correct. Ideally, there should be a test case for this.)
Thanks to Eugen Kuksa for pointing this out.
[[
In
http://hackage.haskell.org/packages/archive/network/latest/doc/html/src/Net…
at
ipvFuture :: URIParser String
ipvFuture =
do { char 'v'
; h <- hexDigitChar
; char '.'
; a <- many1 (satisfy isIpvFutureChar)
; return $ 'c':h:'.':a
}
there should be
; return $ 'v':h:'.':a
]]
#g
--
Hackage: http://hackage.haskell.org/package/options
Home page: https://john-millikin.com/software/haskell-options/
API reference: https://john-millikin.com/software/haskell-options/reference/haskell-option…
The options package lets library and application developers easily
work with command-line options.
The following example is a full program that can accept two options,
--message and --quiet:
----------------------------------------------------------
{-# LANGUAGE TemplateHaskell #-}
import Options
defineOptions "MainOptions" $ do
stringOption "optMessage" "message" "Hello world!"
"A message to show the user."
boolOption "optQuiet" "quiet" False
"Whether to be quiet."
main :: IO ()
main = runCommand $ \opts args -> do
if optQuiet opts
then return ()
else putStrLn (optMessage opts)
----------------------------------------------------------
----------------------------------------------------------
$ ./hello
Hello world!
$ ./hello --message='ciao mondo'
ciao mondo
$ ./hello --quiet
$
----------------------------------------------------------
In addition, this library will automatically create documentation
options such as --help and --help-all:
----------------------------------------------------------
$ ./hello --help
Help Options:
-h, --help Show option summary.
--help-all Show all help options.
Application Options:
--message A message to show the user.
--quiet Whether to be quiet.
----------------------------------------------------------
If you're not otherwise attached to MacPorts, you might want to check
out Homebrew [1]. Its integration with the rest of OS X is generally
more smoothly and I haven't come across any missing packages yet.
[1]: http://mxcl.github.com/homebrew/
On 22 March 2012 16:34, Warren Harris <warrensomebody(a)gmail.com> wrote:
> I assume that many haskell users out there on macs who are also users of macports, and I bet they've hit this same issue that I've hit numerous times. The problem is that there are 2 incompatible versions of libiconv -- one that ships with the mac, and one that's built with macports and that many macports-compiled libraries depend on.
>
> Work-arounds have been documented in numerous places (notably here: http://blog.omega-prime.co.uk/?p=96) but if you are trying to link with a macports-compiled libraries that depends on /opt/local/lib/libiconv.2.dylib, your only alternative seems to be building ghc from source in order to avoid the incompatibility. I hit this problem while trying to build a foreign-function interface to libarchive.
>
> So I built ghc from scratch -- in fact I built the whole haskell-platform. This was relatively painless, and fixed the libiconv problem. However, it brings me to the real point of my message, which is that the version of haskell-platform available via macports is way out of date (2009.2.0.2 http://www.macports.org/ports.php?by=name&substr=haskell-platform)
>
> I'm wondering whether the haskell-platform team has considered maintaining a macports version of the haskell-platform for us mac users in addition to the binary install that's available now. This would avoid the incompatibilities such as this nagging one with libiconv. Perhaps it's just a matter of maintaining template versions of the port files?
>
> Warren
>
> Undefined symbols for architecture x86_64:
> "_locale_charset", referenced from:
> _localeEncoding in libHSbase-4.3.1.0.a(PrelIOUtils.o)
> "_iconv_close", referenced from:
> _hs_iconv_close in libHSbase-4.3.1.0.a(iconv.o)
> (maybe you meant: _hs_iconv_close)
> "_iconv", referenced from:
> _hs_iconv in libHSbase-4.3.1.0.a(iconv.o)
> (maybe you meant: _hs_iconv, _hs_iconv_open , _hs_iconv_close )
> "_iconv_open", referenced from:
> _hs_iconv_open in libHSbase-4.3.1.0.a(iconv.o)
> (maybe you meant: _hs_iconv_open)
> ld: symbol(s) not found for architecture x86_64
> collect2: ld returned 1 exit status
> cabal: Error: some packages failed to install:
> Libarchive-0.1 failed during the building phase. The exception was:
> ExitFailure 1
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe(a)haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
--
Push the envelope. Watch it bend.
On Mon, 19 Mar 2012 14:28:57 -0500, Jeremy Shaw <jeremy(a)n-heptane.com> wrote:
> Does this actually work for you? It builds for me, but when readBinIface'
> is called, it fails because the 'undefined' is apparently actually
> evaluated in GHC 7.4.1.
>
Hmm, frankly this fix was to get another package dependent on plugins to
compile (https://github.com/colah/ImplicitCAD) The program runs without
evaluating undefined, but I suspect this is just because I haven't hit
the relevant codepath.
After a fairly brief look at the relevant documentation, I must say I
don't see any easy solution to this. The undefined in question is a
DynFlags. It seems that DynFlags.defaultDynFlags can give us a DynFlags,
but unfortunately, it needs a Settings value (at least in 7.4), which
has no obvious. It seems the correct way to do this is with
parseDynamicFlags but, alas, this too requires a DynFlags.
Cheers,
- Ben
--------------------------------------------
-- unification-fd 0.7.0
--------------------------------------------
The unification-fd package offers generic functions for single-sorted
first-order structural unification (think of programming in Prolog, or
of the metavariables in type inference)[1][2]. The library *is*
sufficient for implementing higher-rank type systems a la [Peyton Jones,
Vytiniotis, Weirich, Shields], but bear in mind that unification
variables are the metavariables of type inference--- not the type-variables.
An effort has been made to make the package as portable as possible.
However, because it uses the ST monad and the mtl-2 package it can't be
H98 nor H2010. However, it only uses the following common extensions
which should be well supported[3]:
Rank2Types
MultiParamTypeClasses
FunctionalDependencies -- Alas, necessary for type inference
FlexibleContexts -- Necessary for practical use of MPTCs
FlexibleInstances -- Necessary for practical use of MPTCs
UndecidableInstances -- For Show instances due to two-level types
--------------------------------------------
-- Changes (since 0.6.0)
--------------------------------------------
This release is another major API breaking release. Apologies, but
things are a lot cleaner now and hopefully the API won't break again for
a while. The biggest change is that the definition of terms has changed
from the previous:
data MutTerm v t
= MutVar !v
| MutTerm !(t (MutTerm v t))
To the much nicer:
data UTerm t v
= UVar !v
| UTerm !(t (UTerm t v))
The old mnemonic of "mutable terms" was inherited from the code's
previous life implementing a logic programming language; but when I was
playing around with implementing a type checker I realized that the
names don't really make sense outside of that original context. So the
new mnemonic is "unification terms". In addition to being a bit shorter,
it should help clarify the separation of concerns (e.g., between
unification variables vs lambda-term variables, type variables, etc.).
The swapping of the type parameters is so that UTerm can have instances
for Functor, Monad, etc. This change should've been made along with the
re-kinding of variable types back in version 0.6.0, since the UTerm type
is the free monad generated by t. I've provided all the category
theoretic instances I could imagine some plausible reason for wanting.
Since it's free, there are a bunch more I haven't implemented since they
don't really make sense for structural terms (e.g., MonadTrans,
MonadWriter, MonadReader, MonadState, MonadError, MonadCont). If you can
come up with some compelling reason to want those instances, I can add
them in the future.
Since the order of type parameters to BindingMonad, UnificationFailure,
Rank, and RankedBindingMonad was based on analogy to the order for
terms, I've also swapped the order in all of them for consistency.
I've removed the eqVar method of the Variable class, and instead added
an Eq superclass constraint. Again, this should've happened with the
re-kinding of variables back in version 0.6.0. A major benefit of this
change is that now you can use all those library functions which require
Eq (e.g., many of the set-theoretic operations on lists, like (\\) and
elem).
I've added new functions: getFreeVarsAll, applyBindingsAll, freshenAll;
which are like the versions without "All", except they're lifted to
operate over Foldable/Traversable collections of terms. This is crucial
for freshenAll because it allows you to retain sharing of variables
among the collection of terms. Whereas it's merely an optimization for
the others (saves time for getFreeVarsAll, saves space for
applyBindingsAll).
The type of the seenAs function has also changed, to ensure that
variables can only be seen as structure rather than as any UTerm.
Thanks to Roman Cheplyaka for suggesting many of these changes.
--------------------------------------------
-- Description
--------------------------------------------
The unification API is generic in the type of the structures being
unified and in the implementation of unification variables, following
the two-level types pearl of Sheard (2001). This style mixes well with
Swierstra (2008), though an implementation of the latter is not included
in this package.
That is, all you have to do is define the functor whose fixed-point is
the recursive type you're interested in:
-- The non-recursive structure of terms
data S a = ...
-- The recursive term type
type PureTerm = Fix S
And then provide an instance for Unifiable, where zipMatch performs one
level of equality testing for terms and returns the one-level spine
filled with pairs of subterms to be recursively checked (or Nothing if
this level doesn't match).
class (Traversable t) => Unifiable t where
zipMatch :: t a -> t b -> Maybe (t (a,b))
The choice of which variable implementation to use is defined by
similarly simple classes Variable and BindingMonad. We store the
variable bindings in a monad, for obvious reasons. In case it's not
obvious, see Dijkstra et al. (2008) for benchmarks demonstrating the
cost of naively applying bindings eagerly.
There are currently two implementations of variables provided: one based
on STRefs, and another based on a state monad carrying an IntMap. The
former has the benefit of O(1) access time, but the latter is plenty
fast and has the benefit of supporting backtracking. Backtracking itself
is provided by the logict package and is described in Kiselyov et al.
(2005).
In addition to this modularity, unification-fd implements a number of
optimizations over the algorithm presented in Sheard (2001)--- which is
also the algorithm presented in Cardelli (1987).
* Their implementation uses path compression, which we retain. Though we
modify the compression algorithm in order to make sharing observable.
* In addition, we perform aggressive opportunistic observable sharing, a
potentially novel method of introducing even more sharing than is
provided by the monadic bindings. Basically, we make it so that we can
use the observable sharing provided by the modified path compression as
much as possible (without introducing any new variables).
* And we remove the notoriously expensive occurs-check, replacing it
with visited-sets (which detect cyclic terms more lazily and without the
asymptotic overhead of the occurs-check). A variant of unification which
retains the occurs-check is also provided, in case you really need to
fail fast.
* Finally, a highly experimental branch of the API performs *weighted*
path compression, which is asymptotically optimal. Unfortunately, the
current implementation is quite a bit uglier than the unweighted
version, and I haven't had a chance to perform benchmarks to see how the
constant factors compare. Hence moving it to an experimental branch.
These optimizations pass a test suite for detecting obvious errors. If
you find any bugs, do be sure to let me know. Also, if you happen to
have a test suite or benchmark suite for unification on hand, I'd love
to get a copy.
--------------------------------------------
-- Notes and limitations
--------------------------------------------
[1] At present the library does not appear amenable for implementing
higher-rank unification itself; i.e., for higher-ranked metavariables,
or higher-ranked logic programming. To be fully general we'd have to
abstract over which structural positions are co/contravariant, whether
the unification variables should be predicative or impredicative, as
well as the isomorphisms of moving quantifiers around. It's on my todo
list, but it's certainly non-trivial. If you have any suggestions, feel
free to contact me.
[2] At present it is only suitable for single-sorted (aka untyped)
unification, a la Prolog. In the future I aim to support multi-sorted
(aka typed) unification, however doing so is complicated by the fact
that it can lead to the loss of MGUs; so it will likely be offered as an
alternative to the single-sorted variant, similar to how the weighted
path-compression is currently offered as an alternative.
[3] With the exception of fundeps which are notoriously difficult to
implement. However, they are supported by Hugs and GHC 6.6, so I don't
feel bad about requiring them. Once the API stabilizes a bit more I plan
to release a unification-tf package which uses type families instead,
for those who feel type families are easier to implement or use. There
have been a couple requests for unification-tf, so I've bumped it up on
my todo list.
--------------------------------------------
-- References
--------------------------------------------
Luca Cardelli (1987) /Basic polymorphic typechecking/.
Science of Computer Programming, 8(2):147--172.
Atze Dijkstra, Arie Middelkoop, S. Doaitse Swierstra (2008)
/Efficient Functional Unification and Substitution/,
Technical Report UU-CS-2008-027, Utrecht University.
<http://www.cs.uu.nl/research/techreps/repo/CS-2008/2008-027.pdf>
Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, Mark
Shields /Practical type inference for arbitrary-rank types/,
to appear in the Journal of Functional Programming.
(Draft of 31 July 2007.)
Oleg Kiselyov, Chung-chieh Shan, Daniel P. Friedman, and
Amr Sabry (2005) /Backtracking, Interleaving, and/
/Terminating Monad Transformers/, ICFP.
<http://www.cs.rutgers.edu/~ccshan/logicprog/LogicT-icfp2005.pdf>
Tim Sheard (2001) /Generic Unification via Two-Level Types/
/and Paramterized Modules/, Functional Pearl, ICFP.
<http://web.cecs.pdx.edu/~sheard/papers/generic.ps>
Tim Sheard & Emir Pasalic (2004) /Two-Level Types and/
/Parameterized Modules/. JFP 14(5): 547--587. This is
an expanded version of Sheard (2001) with new examples.
<http://web.cecs.pdx.edu/~sheard/papers/JfpPearl.ps>
Wouter Swierstra (2008) /Data types a la carte/, Functional
Pearl. JFP 18: 423--436.
<http://www.cs.ru.nl/~wouters/Publications/DataTypesALaCarte.pdf>
--------------------------------------------
-- Links
--------------------------------------------
Homepage:
http://code.haskell.org/~wren/
Hackage:
http://hackage.haskell.org/package/unification-fd
Darcs:
http://community.haskell.org/~wren/unification-fd
Haddock (Darcs version):
http://community.haskell.org/~wren/unification-fd/dist/doc/html/unification…
--
Live well,
~wren
Here are a few patches to get hs-plugins compiling again on GHC 7.4.1. The
first I stole from Brian Victor[1], while the second simply replaces
addrToHValue# with addrToAny# (a change apparently made in 7.4). There
are active codebases that rely on this package so it would be
appreciated if someone could push a new release of plugins with these
applied. Thanks!
Cheers,
- Ben
[1] http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/95185
P.S. Sorry, my darcs-fu isn't particluarly strong, so I ended I having
to edit the patches by hand to separate the changes. Hopefully they'll
still apply on your end.
diff -rN -u old-hs-plugins/src/System/Plugins/Load.hs new-hs-plugins/src/System/Plugins/Load.hs
--- old-hs-plugins/src/System/Plugins/Load.hs 2012-03-04 22:52:59.049531108 -0500
+++ new-hs-plugins/src/System/Plugins/Load.hs 2012-03-04 22:52:59.221531962 -0500
@@ -84,9 +84,15 @@
import System.Directory ( doesFileExist, removeFile )
import Foreign.C.String ( CString, withCString, peekCString )
+#if !MIN_VERSION_ghc(7,2,0)
import GHC ( defaultCallbacks )
+#endif
import GHC.Ptr ( Ptr(..), nullPtr )
#if DEBUG
@@ -99,7 +105,11 @@
readBinIface' :: FilePath -> IO ModIface
readBinIface' hi_path = do
-- kludgy as hell
+#if MIN_VERSION_ghc(7,2,0)
+ e <- newHscEnv undefined
+#else
e <- newHscEnv defaultCallbacks undefined
+#endif
initTcRnIf 'r' e undefined undefined (readBinIface IgnoreHiWay QuietBinIFaceReading hi_path)
-- TODO need a loadPackage p package.conf :: IO () primitive
@@ -679,7 +693,11 @@
-- and find some packages to load, as well.
let ps = dep_pkgs ds
+#if MIN_VERSION_ghc(7,2,0)
+ ps' <- filterM loaded . map packageIdString . nub $ map fst ps
+#else
ps' <- filterM loaded . map packageIdString . nub $ ps
+#endif
#if DEBUG
when (not (null ps')) $
diff -rN -u old-hs-plugins/src/System/Plugins/Load.hs new-hs-plugins/src/System/Plugins/Load.hs
--- old-hs-plugins/src/System/Plugins/Load.hs 2012-03-04 22:53:01.073541145 -0500
+++ new-hs-plugins/src/System/Plugins/Load.hs 2012-03-04 22:53:01.229541919 -0500
@@ -84,9 +84,15 @@
import GHC.Ptr ( Ptr(..), nullPtr )
+#if !MIN_VERSION_ghc(7,4,1)
import GHC.Exts ( addrToHValue# )
+#else
+import GHC.Exts ( addrToAny# )
+#endif
import GHC.Prim ( unsafeCoerce# )
#if DEBUG
@@ -445,7 +455,11 @@
ptr@(Ptr addr) <- withCString symbol c_lookupSymbol
if (ptr == nullPtr)
then return Nothing
+#if !MIN_VERSION_ghc(7,4,1)
else case addrToHValue# addr of
+#else
+ else case addrToAny# addr of
+#endif
(# hval #) -> return ( Just hval )
So now that we have void in Control.Monad, can we remove it from
Foreign.Marshal.Error? Or at least make them the same function? It's
mildly annoying when importing both Control.Monad and Foreign winds up
with ambiguous symbol errors.
> From: Max Bolingbroke <batterseapower(a)hotmail.com>
>
> Hi Haskellers,
>
> I propose to add a new function, traverseWithKey, to Data.Map:
>
+1
Does it make sense to additionally add traverseWithKey to Data.IntMap?
John L.