Fork me on GitHub
#test-check
<
2021-03-04
>
hiredman21:03:32

it seems unlikely, but I think you should be able to get by with a single fmap

gfredericks21:03:23

Equal length strings?

hiredman21:03:13

generate a string of more than n characters, generate a vector of n characters and indices, then fmap over both of those producing a pair of the string, and the string with characters swapped at the indices

hiredman21:03:56

(the indices will require some fiddling to work out right, but doable)

gfredericks21:03:05

You could also generate edit operations

hiredman21:03:35

yeah, characters + indices are an edit operation

murtaza21:03:35

What I've done so far is generate a string, and then edit out parts of it at random start and end positions using subs, joins and replace

hiredman21:03:35

no, I don't think you can do it without an fmap

gfredericks21:03:20

Random meaning calling rand-int or similar?

gfredericks21:03:03

Tied together with bind and fmap?

hiredman21:03:27

in order for the generator to work at all, you need to at the base to be able to turn 1 string in to a pair of strings

hiredman21:03:42

that is gonna be an fmap

gfredericks21:03:34

I think generating edits is pretty easy, though it might be harder to aim for exactly N differences if you need that

gfredericks21:03:54

Generating edits would shrink nicely I think

gfredericks21:03:07

If you want to shrink toward fewer differences

hiredman21:03:32

;; written but not run
;; assuming strings of length 5 and differences of 3 characters
(gen/fmap
 (fn [string edits]
   (loop [[[shift index] & es] edits
          s (vec string)
          editted #{}]
     (if e
       (let [i (mod index (count s))]
         (if (contains? editted i)
           (recur (cons [shift (inc index)] es) s editted)
           (recur es
                  (update-in s [i] (fn [c]
                                     (char (+ 32 (mod (+ offset (- (int c) 32)) 126)))))
                  (conj editted i))))
       (apply str s))))
 (gen/tuple (gen/resize 5 gen/string-ascii)
            (gen/tuple
             (gen/tuple s-pos-int s-pos-int)
             (gen/tuple s-pos-int s-pos-int)
             (gen/tuple s-pos-int s-pos-int))))

hiredman21:03:50

(that mod 126 should maybe be mod 126 - 32)

hiredman21:03:26

and the fn has to destructure the vector, etc

robertfw21:03:07

Can you recur from there?

hiredman21:03:24

inside a loop? of course

robertfw21:03:52

I meant from non-tail position

hiredman21:03:08

I am pretty sure those are all tails

robertfw22:03:25

I thought I had run into not being able to recur from the first branch of if but I may well be getting mixed up with recur within try

hiredman22:03:51

yes, you can't recur across a try, logically a try pushes an exception handler on to a stack, so recuring across a try grows the exception handling stack

robertfw22:03:40

Thanks, that makes sense