I have seen some amazing AI Python code generation examples. Has anyone had success having an AI generate Haskell code?
Old school AI is pretty good at it:
djinn might have a problem doing this ChatGPT o1 preview + mini Wrote My PhD Code in 1 Hour*—What Took Me ~1 Year
I spent a weekend messing around with GPT a few months ago.
The idea was to convert a lot of code and documentation from the libraries I was working with into vector form and use semantic search to search this code base and add the most relevant parts in the query. I was basically hoping it could extract patterns and use these to generate useful code.
Then I provided gpt with an interface so it could submit code to run, and the output of this code would be sent back to it, it also had access to the semantic search and could query for more information.
Basically, I would ask it something, for example I was using reflex-frp I included all the relevant reflex documentation and code. Then I would ask something like, can you create a reflex-frp scroll widget.
It would then run for a long time, submitting code and the code nearly always failed, the errors would be fed back in, I was able to get some working code from it, after it ran for a long time.
Honestly though it was a failed experiment, it would nearly always take the wrong turn and go down dead ends in reasoning, you had to run it, find these and explicitly tell it to not try them for a fresh run.
Ultimately the message size became too big before anything usable was generated and it was expensive to run.
I think Python is a lot better with the LLM’s I would guess other languages like JS are the same, so comparatively simple languages with a lot of documentation and discussion online. I think the LLM’s really struggle with languages like C++, C and Haskell in my experience. I don’t think there is enough training data for something like Haskell. With C and C++ it generates a lot of poor-quality code that will hurt in the long run. The pure quality of the C code is probably just a reflection of the standard of C in its training data.
It’s entirely possible with some more engineering and better prompts what I built could have been made to work, but in the end, it was clear to me it was better if I simply just became familiar with the libraries myself, so it was more efficient just to train up my own internal mental models.
With regard creating a whole PhD I would guess this guy learned a lot in the year he spent writhing it (arguably one of the reasons for doing such a project) so when he was creating the prompt he knew what to prompt. I would guess if he started from scratch, he could have also got the code written in a fraction of the time. I mean the fact he instantly knew what he was looking at was correct kinda showed his deep understanding of the topic.
What I mean by this is being an expert on something and knowing what to prompt is different to needing a solution for something you’re not an expert on. An extreme of this might be the Douglas Adams joke about the meaning of life being 42.
The other thing is that LLM’s to me are function approximation tool on steroids. The training data is the internet so you will get the average of the internet’s knowledge. This seems to line up with my experience if you are doing something that is new to you but done a thousand times a day by others, then the LLM is quite good at it, but if you’re doing something new and interesting it nearly always fails and becomes counterproductive.
So, for me at least I like to use the LLM to get an understanding on the average or common approaches to problems. I like it for quickly testing ideas against or learning new concepts, but I aim to internalize the knowledge. It should be pretty obvious but worth saying, running using any code you dont fully understand is a bad idea unless you trust the author and for me at least I dont trust gpt.
Anyway, I hope some of this helps.
Thanks, Great Answer! Just starting to mess with Claude AI. I’ll let you know how it goes.
I tried more than a year ago. Twice.
Since then I learned more about AI and the LLMs themselves have improved, so I probably should try again.
I found them very useful (Sonnet is my current fave even after the new 1o release) and getting better all the time.
Having said that, they still require effort and not infallible (sometimes it takes multiple shots to get things right).
I have been trying Claude AI and it refuses to generate many of my requests due to “ethical” concerns and risks that are inherent to any app that has a user direct messages and chat rooms. Have you found this to be problematic with Sonnet?
Literally just today I was asking it for some help while I fix my oven (dogey thermal switch) it refused for safety reasons
I was just asking it for information on a part number and it told me to stop and talk to a professional
I had to remind it that it’s an oven not a nuclear reactor
I had to shame it with
All the risks you raise are risks that exist on existing social media platforms that you are recommending me use, so your refusal is illogical. Your statement also implies that all social internet site have so much risk that they should not have been produced in the first place and should be shut down.
to give me an answer
I think I’m just going to start lying up front and telling it that I am an agent of the federal government and have a court order that states it must produce a valid answer to my request.
I’m impressed with how well ChatGPT understands Haskell. I asked it for some sample code using Megaparsec to solve a toy problem, and then modified that to get what I actually wanted. At some point a parser was looping forever and I couldn’t figure out why, and I asked it, and it found a solution, using notFollowedBy to look for what comes next without consuming it.
There have been moments where I found LLMs v creative.
E.g. describing a novel visualisation in Python (which I could describe but couldn’t do with matplotlib).
Of course, it’s probably not truly creative. It saw a similar solution in its training set, but nevertheless, it saved me time.
And, tbh, I see it shining more in Haskell.
Perhaps because I value Haskell more than say Python or Rust.
Also Haskell libraries often bring new concepts with them, sometimes tricky, and LLMs make things easier.
Claude AI wrote some trivial stuff well
toBytes :: (FiniteBits a, Integral a) => a -> [Word8]
toBytes x = map (fromIntegral . shiftR x) [n, n-8 .. 0]
where n = finiteBitSize x - 8
I’ll keep working it to see what it can do.
After a brief chat with ChatGPT I could come up with this. The only thing that did not go right was the pattern matching againt the 2 different constructors:
-- Define the ReportTree3 data structure
data ReportTree3 a = ReportNode3
{ value :: a -- Holds the value for the node
, children :: [ReportTree3 a] -- List of child nodes
} deriving (Show)
-- Define the data type for report items
data ReportItem3
= ReportItemAccount3 { id :: Int, label :: Text, tab :: Int, amount :: Double, account :: Int } -- Leaf node with account info
| ReportItemHeader3 { amount :: Double, id :: Int, label :: Text, tab :: Int } -- Header node with an amount field
deriving (Generic, Show)
-- Function to update the tree so that each `ReportItemHeader3` node's `amount` field
-- holds the sum of all elements in its subtree
updateSubtreeSums2 :: ReportTree3 ReportItem3 -> ReportTree3 ReportItem3
updateSubtreeSums2 (ReportNode3 value children) =
-- First, update all child nodes with their subtree sums
let updatedChildren = Data.List.map updateSubtreeSums2 children
-- Calculate the sum of the amounts of all updated child nodes
-- ChatGPT did this-> sumOfChildrenAmounts = sum (Data.List.map (amount . value) updatedChildren)
sumOfChildrenAmounts = sum (Data.List.map (\value -> do
case value of
ReportNode3{value} -> case value of
ReportItemAccount3 {amount} -> amount
ReportItemHeader3 {amount} -> amount
) updatedChildren)
-- Calculate the new amount for the current node based on its type
newAmount = case value of
-- For `ReportItemAccount3` (leaf nodes), amount remains the same
ReportItemAccount3 { amount } -> amount
-- For `ReportItemHeader3`, the amount is the sum of its own value and its children's values
ReportItemHeader3 { amount } -> amount + sumOfChildrenAmounts
-- Return the updated node with the new amount value
in case value of
-- Update `ReportItemHeader3` with the new calculated amount
ReportItemHeader3 _ id label tab -> ReportNode3 (ReportItemHeader3 newAmount id label tab) updatedChildren
-- For `ReportItemAccount3`, return the node as it is
ReportItemAccount3 {} -> ReportNode3 value updatedChildren
So, I think it works at least okayishly
try claude : ) far better for me with niche languages (and non-niche ones)