4

Suppose I wanted a function of type [[a]] -> [[b]] -> [[(a, b)]]. I'm sure I could figure something out, but chances are, it wouldn't be as clean as, for example, zipWith zip, which also has that type.

Entering this type signature into Hoogle gives me a few functions that fill this role, but they come from the leancheck and extrapolate packages, which I wouldn't want to drag into my project without a good reason.

Given that you can compute function composition through equational reasoning, I am wondering if there is an inverse to this process: is there a way that I could “factorize” a complex type signature and reduce it down to its simplest function composition?

MikaelF
  • 3,518
  • 4
  • 20
  • 33
  • 3
    This sounds a bit like djinn: http://hackage.haskell.org/package/djinn – Willem Van Onsem Jul 23 '19 at 17:53
  • 11
    Surely the **simplest** would be `\_ _ -> []`. This objection may feel silly to you, but it is a serious one: `zipWith zip` is by no means the obvious, canonical, only sensible function of this type. I can think of at least two other quite sensible and useful ones besides this silly, unuseful one (and myriad other silly, unuseful ones). – Daniel Wagner Jul 23 '19 at 17:54
  • I really can't follow what you mean by "factorise" a type signature. The example you give has nothing to do with making any changes to the type signature, and `zipWith zip` isn't a composition. In any event, composition combines (function) *values*, not types. – Robin Zigmond Jul 23 '19 at 17:55
  • 3
    @RobinZigmond: based on the question, I think the OP wants to automatically generate functions, based on type signatures. – Willem Van Onsem Jul 23 '19 at 17:59
  • There are many functions of this type, the ones you've found in existing packages are not related to `zipWith zip`. – n. m. could be an AI Jul 23 '19 at 18:00
  • @RobinZigmond Thank you for your comment. Willem Van Onsem had it right, I think the package he pointed at was what I wanted. It's just too bad it has no documentation. – MikaelF Jul 23 '19 at 18:03
  • 2
    (...and if djinn is up your alley, see also [exference](https://github.com/lspitzner/exference); unlike djinn, it can handle recursive types like lists, though at the cost that it may not terminate if you ask it a really hard one.) – Daniel Wagner Jul 23 '19 at 18:06
  • @DanielWagner I think the reason I hadn't thought of that is probably the same reason I don't suspect a library function will return `undefined`, even though it would typecheck: I was thinking of non-trivial implementations. Cheers for your objection, though. I will also look into `exference`. – MikaelF Jul 23 '19 at 18:09
  • 3
    Also my toy project [djest](https://github.com/luqui/djest) may be up your alley. It generates functions of a given type signature and looks for ones that pass a test you give it. E.g. `length (f xs ys) == min (length xs) (length ys)` might find yours. (I really need to clean it up for usability though.) – luqui Jul 23 '19 at 19:31
  • There are types for which the question of whether or not values exist is undecidable. – Jeremy List Jul 25 '19 at 23:02

1 Answers1

1

Thank you to DanielWagner and Willem Van Onsem, who answered my question in the comments. What I thought was some sort of category-theory factorization turned out to simply be code generation.

The package exference does just what I wanted. From the documentation:

Type inference takes an expression and tells you its type. This process can be inversed: We recursively create random expression trees while checking that they -so far- match a given input type. At each step we do the backwards step of the inference algorithm step. If you are lucky, this search yields one or more expressions.


The package djinn also does code generation from type expressions, but supports less types, and has little documentation. However, it is guaranteed to always terminate, unlike exference.

For emacs users, it seems that djinn is already integrated into ghc-mod.


There is also Djest, by luqui, which is somewhat in between Quickcheck and the previous tools. It allows you to enter a few sets of input and output, for which the program will try and make up a function that satisfies them.

Thanks to all those who contributed and made me discover these packages.

MikaelF
  • 3,518
  • 4
  • 20
  • 33