Curry
Swift implementations for function currying
I recently followed through A Taste of Curry, and afterwards decided to put the trivial arithmetic parser example to test, by writing a somewhat more substantial parser: a primitive but correct and functional HTML parser.
I ended up with a working node2string
function to operate on Node
(with attributes and children), which I then inverse
d to obtain a parse
function, as exemplified in the article.
The first naive implementation had the mistake that it parsed anything but e.g. the trivial <input/>
HTML snippet into exactly one Node
representation; everything else nondeterministically yielded invalid things like
Node { name = "input", attrs = [Attr "type" "submit"] }
Node { name = "input type=\"submit\"", attrs = [] }
and so on.
After some initial naive attempts to fix that from within node2string
, I realized the point, which I believe all seasoned logic programmers see instantaneously, that parse = inverse node2string
was right more right and insightful about the sitatution than I was: the above 2 parse results of <input type="submit"/>
indeed were exactly the 2 valid and constructible values of Node
that would lead to HTML representations.
I realized I had to constrain Node
to only allow passing in alphabetic — well not really but let's keep it simple — names (and of course same for Attr
). In a less fundamental setting than a logic program (such as regular Haskell with much more hand written and "instructional" as opposed to purely declarative programming), I would simply have hidden the Node
constructor behind e.g. a mkNode
sentinel function, but I have the feeling this wouldn't work well in Curry due to how the inference engine or constraint solver work (I might be wrong on this, and in fact I hope I am).
So I ended up instead with the following. I think Curry metaprogramming (or Template Haskell, if Curry supported it) could be used ot clean up the manual boielrplate, but cosmetically dealing is only one way out of the situation.
data Name = Name [NameChar] -- newtype crashes the compiler
data NameChar = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
name2char :: NameChar -> Char
name2char c = case c of A -> 'a'; B -> 'b'; C -> 'c'; D -> 'd'; E -> 'e'; F -> 'f'; G -> 'g'; H -> 'h'; I -> 'i'; J -> 'j'; K -> 'k'; L -> 'l'; M -> 'm'; N -> 'n'; O -> 'o'; P -> 'p'; Q -> 'q'; R -> 'r'; S -> 's'; T -> 't'; U -> 'u'; V -> 'v'; W -> 'w'; X -> 'x'; Y -> 'y'; Z -> 'z'
name2string :: Name -> String
name2string (Name s) = map name2char s
-- for "string literal" support
nameFromString :: String -> Name
nameFromString = inverse name2string
data Node = Node { nodeName :: Name, attrs :: [Attr], children :: [Node] }
data Attr = Attr { attrName :: Name, value :: String }
attr2string :: Attr -> String
attr2string (Attr name value) = name2string name ++ "=\"" ++ escape value ++ "\""
where escape = concatMap (\c -> if c == '"' then "\\\"" else [c])
node2string :: Node -> String
node2string (Node name attrs children) | null children = "<" ++ name' ++ attrs' ++ "/>"
| otherwise = "<" ++ name' ++ attrs' ++ ">" ++ children' ++ "</" ++ name' ++ ">"
where name' = name2string name
attrs' = (concatMap ((" " ++) . attr2string) attrs)
children' = intercalate "" $ map (node2string) children
inverse :: (a -> b) -> (b -> a)
inverse f y | f x =:= y = x where x free
parse :: String -> Node
parse = inverse node2string
This, in fact, works perfectly (in my judgement):
Parser> parse "<input type=\"submit\"/>"
(Node [I,N,P,U,T] [(Attr [T,Y,P,E] "submit")] [])
Parser> parse "<input type=\"submit\" name=\"btn1\"/>"
(Node [I,N,P,U,T] [(Attr [T,Y,P,E] "submit"),(Attr [N,A,M,E] "btn1")] [])
(Curry doesn't have type classes so I wouldn't know yet how to make [NameChar]
print more nicely)
However, my question is:
is there a way to use something like isAlpha
(or a function more true to the actual HTML spec, of course) to achieve a result equivalent to this, without having to go through the verbose boilerplate that NameChar
and its "supporting members" are? There seems to be no way to even place the "functional restriction" anywhere within the ADT.
In a Dependently Typed Functional Logic Programming language, I would just express the constraint at the type level and let the inference engine or constraint solver deal with it, but here I seem to be at a loss.
Source: (StackOverflow)
Does Curry have the ability to show or pretty print data types inside the REPL (using PAKCS or MCC)? In Haskell, this functionality is impemented using the type class Show
. However, no maintained Curry implementation implements type classes. Glancing at the PAKCS libraries, it appears that no abstract data type is given a canonical representation for the user to interact with, but several have separate functions defined for pretty printing them.
For reference, I am implementing several abstract data types for a personal project. Because I have no intention of packaging the code into a compiled program with an interactive user interface, something approximating Haskell's show
function would be convenient.
Source: (StackOverflow)
Below is my first program in Curry. It prints sequence of steps required for reaching a desired solution (walking through a closed door).
Evaluating expression: main
Done
(Just [Open,Walk,Close])
How can I make it terminate when looking for Impossible
? I am using Kics2 0.3.1.
import List
import AllSolutions
import IO
import ReadShowTerm
import Constraint
data State = Opened | Closed | Outside | Done | Impossible
data Action = Open | Walk | Close
e Open Closed = Opened
e Walk Opened = Outside
e Close Outside = Done
solution target | foldl (flip e) Closed actions =:= target & length actions <: 4 = actions
where actions free
main = do
target <- getContents
getOneValue (solution $ readTerm target) >>= print
Source: (StackOverflow)
What's the most practical way to write a program in Curry programming language that would have a console UI with decent line editing?
Actually, I need to pass a string as a suggestion for the user's input, then let the user edit it in the console, and receive his edited variant back, process it (w.r.t. to the current state of the process), then loop.
I like readline-like/haskeline-like editing. (And BTW haskeline in its latest version (0.6.4.0) has exactly the API for what I want: read a line with a suggested initial value -- getInputLineWithInitial
:
This function behaves in the exact
same manner as getInputLine
, except
that it pre-populates the input area.
The text that resides in the input
area is given as a 2-tuple with two
Strings. The string on the left of the
tuple is what will appear to the left
of the cursor and the string on the
right is what will appear to the right
of the cursor.
)
How to get the wanted functionality for a Curry program in the most practical way (I mean, I'd like not to write new code in Curry for the console editing operations, but rather perhaps use a library, or a wrapper, or FFI)?
Source: (StackOverflow)
The rather fascinating 2013 introductory post to the Haskell based KiCS2 implementation of Curry by Wolfgang Jeltsch, A Taste of Curry, provides the following definition for the inverse
combinator:
inverse :: (a -> b) -> (b -> a)
inverse f y | f x =:= y = x where x free
(Note: this does things like inverse (+1) 3 == 2
and inverse (*3) 12 == 4
and inverse htmlHodeToStr == parseHtmlNode
, and an infinity of other unbelievably awesome things, for passers by not familiar with Curry)
Furthermore, it also offers 2 alternative but equivalent definitions of the (non-deterministic) split :: [a] -> ([a], [a])
function:
split :: [a] -> ([a],[a])
split list | front ++ rear =:= list = (front,rear)
and
split' :: [a] -> ([a],[a])
split' (xs ++ ys) = (xs,ys)
as well as some other rather enlightening definitions, which are however beyond the scope of this post.
However, my thinking led me to attempt an alternative, compacted definition of inverse
in the spirit of split
and split'
:
inverse' :: (a -> b) -> (b -> a)
inverse' f (f x) = x
this, on the other hand, leads to the following error:
Undefined data constructor `f'
My question: why does Curry interpret the f
in the would-be functional pattern (f x)
as a data constructor, but the ++
in the (also functional) pattern (xs ++ ys)
as a function name?
In other words, the xs
and ys
in split' (xs ++ ys) = (xs,ys)
seem to be just exactly analogous to the x
in inverse' f (f x) = x
.
Or if the analogy with split'
is not immediately obvious, consider prefix (xs ++ _) = xs
or orig (1 + x) = x
etc, both of which compile and run just fine.
P.S. I've adapted the names and type signatures just a little bit compared to the original post, for the sake of making this question easier to follow.
Source: (StackOverflow)
I was pretty amazed by the power of prolog. It took some time to get the head around, but to me it seemed to be the coolest declarative language out there. That's why recently, after two years of some functional programming with scala, I decided to take a look at logical programming again, to "train my brain" or better for actual usage.
Combining functional and logical programming seems attractive for me to learn/solidify concepts of both declarative paradigms.
I find also find strong type systems very useful and fascinating.
Scala really shined with interop. Let's not reinvent wheels. It should be able to call code in another main language, and preferable also to be callable. But it doesn't have to be java. C or haskell would be ok too.
So, which are the most useful and enlightening FLP languages today, and what are your opinions and recommendations on them?
Here is what I found so far:
1) mercury: claims to be fast, strongly typed prolog. Pure declarative, but no logical variables! No constraint programming? Seems to be the most widely used FLP. interop??
2) curry: seems promising and the most advanced, a bit low on documentation. Does "experimental" mean immature /not ready to dive into ? just based on haskell or actually good interop with haskell?
3) ciao: seems to provide many features I want, but stackoverflow doesn't even seem to know it at all, although it exists since 1984? What's wrong with it? Interop?
4) drools (java library/DSL): claims it allows hybrid forward- and backward chaining. mature. direct interop with java/scala, but relying on mutable data / imperative constructs? How well does it integrate with functional JVM languages?
5) miniKanren: implementations exist on several platform. How is interop? efficient?
Lambda prolog implementations such as:
6) caledon: Might be nice but heavy theory. Usefullness? Effective interop with Haskell? Documentation?
7) teyjus. similar to caledon.
Good but theoretic reads and biased toward curry and not adressing practical concerns:
http://doi.acm.org/10.1145/1721654.1721675
http://www.informatik.uni-kiel.de/~mh/slides/ETAPS00.pdf
thanks for your answers
Source: (StackOverflow)
I have a standard datatype representing formulae of predicate logic. A function representing a natural deduction elimination rule for disjunction might look like:
d_el p q =
if p =: (Dis r s) && q =: (Neg r) then Just s else
if q =: (Dis r s) && p =: (Neg r) then Just s else
Nothing where r,s free
x =: y = (x =:= y) == success
Instead of evaluating to Nothing when unification fails, the function returns no solutions in PACKS
:
logic> d_el (Dis Bot Top) (Not Bot)
Result: Just Top
More Solutions? [Y(es)/n(o)/a(ll)] n
logic> d_el (Dis Bot Top) (Not Top)
No more solutions.
What am I missing, and why doesn't el
evaluate to Nothing
when unification fails?
Source: (StackOverflow)
Consider a function choose
in Curry programming language with the specification that "(choose xs)
non-deterministically chooses one element from the list xs
".
I'd implement it straighforwardly through two alternative non-deterministic rules:
choose :: [a] -> a
choose x:_ = x
choose _:xs = choose xs
But in /usr/lib/curry-0.9.11/Success.curry from Muenster Curry Compiler, it is defined with a helper function:
choose (x:xs) = choosep x xs
where choosep x [] = x
choosep x (_:_) = x
choosep _ (x:xs) = choosep x xs
What could be the advantages (if any) of the definition from the compiler supplied module?
Are the 2 definitions completely equivalent (even in some tricky cases with non-determinism and undefined values)?.. Is one of them more efficient in some cases?
ADDED: Deeper consideration
cthom06 (Thanks!) has correctly pointed out that my definition would cause hitting the undefined value in much more cases (because we would try to call this function with an empty-list argument once per each our "top-level" call with an initially non-empty list argument). (Hm, why haven't I noticed this consideration right away?..) That is less efficient.
But I wonder: are there any semantic differences? May the difference be important in some tricky contexts?
We see that the difference between the two definitions--in the case of non-empty lists--basically boils down to the difference between two potential definitions for id
:
my definition is like defining id
as:
id x = x
id _ = undefined
and their definition is like definig id
the normal way:
id x = x
(So, here the straightforwardness is reverted.)
In which contexts can it be important?
Source: (StackOverflow)
I found Curry on Wikipedia. It says Curry is nearly a superset but not because of lacking of something.
I'd like to see it support whole Haskell. Did they plan to implement Haskell as a part of Curry?
Source: (StackOverflow)
I would like to ask you about what formal system could be more interesting to implement from scratch/reverse engineer.
I've looked through some existing and rather open (open in the sense of free/open-source) projects of logical/declarative programming systems. I've decided to make up something similar in my free time, or at least to catch the general idea of implementation.
It would be great if some of these systems would provide most of the expressive power and conciseness of modern academic investigations in logic and it's relation with computational models.
What would you recommend to study at least at the conceptual level? For example, Lambda-Prolog is interesting particularly because it allows for higher order relations, but AFAIK (I might really be mistaken :)) is based on intuitionist logic and therefore lack the excluded-middle principle; that's generally a disatvantage for me..
I would also welcome any suggestions about modern logical programming systems which are less popular but more expressive/powerful. I guess, this question will need refactoring, but thank you in advance! :)
Source: (StackOverflow)
From section 3.13.3 of the curry tutorial:
Operations that residuate are called rigid , whereas operations that narrow are called flexible. All defined operations are flexible whereas most primitive operations, like arithmetic operations, are rigid since guessing is not a reasonable option for them. For example, the prelude defines a list concatenation operation as follows:
infixr 5 ++
...
(++) :: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x : xs ++ ys
Since the operation “++” is flexible, we can use it to search for a list satisfying a particular property:
Prelude> x ++ [3,4] =:= [1,2,3,4] where x free
Free variables in goal: x
Result: success
Bindings:
x=[1,2] ?
On the other hand, predefined arithmetic operations like the addition “+” are rigid. Thus, a
call to “+” with a logic variable as an argument flounders:
Prelude> x + 2 =:= 4 where x free
Free variables in goal: x
*** Goal suspended!
Curry does not appear to guard against writing goals that will be suspended. What type systems can detect ahead of time whether a goal is going to be suspended?
Source: (StackOverflow)
when I configure curry's compiler zinc, I get this:
checking for Haskell 98 compiler...
checking for ghc... ghc
checking ghc version... 7.0
checking whether ghc supports Haskell 98... [1 of 1] Compiling Main ( conftest.hs, conftest.o )
yes
using ghc for compilation
checking how to import IOExts... configure: error: import of IOExts does not work
so what's IOExts? where can I find it?
Source: (StackOverflow)