Note: no need for #collect:thenFold: family, one can implement min as

  min
    ^ self detectMin: [ :x | x ]

if you want to reuse existing one.

But actually, the issue is, min: and max: are not there (correctly) for strings.

Herby

Richard O'Keefe wrote:
#('a' 'b' 'c') min
also fails on the grounds that ByteStrings don't understand #min:.
What's worse is that ByteString and ByteSymbol *do* have #max:,
but it's something quite different (and arguably broken).

max: aBlock
     | max |
     self ifEmpty: [ ^ nil ].
     max := aBlock value: self first.
     self
         allButFirstDo:
             [ :each |
             | value |
             value := aBlock value: each.
             max := max max: value ].
     ^ max

It would be better if the TComparable #min: and #max:
were available and the current #max: renamed to something else.
I have this in an extension to GNU Smalltalk:

Collection extend [
     collect: collectBlock thenFold: foldBlock [
         |started result|
         started := result := nil.
         self do: [:each | |v|
             v := collectBlock value: each.
             result := started ifNil: [started := self. v]
                            ifNotNil: [foldBlock value: result value: v]].
         ^started ifNil: [SystemExceptions.EmptyCollection signalOn: self]
               ifNotNil: [result]
     ]

     collectThenMin: collectBlock [
         ^self collect: collectBlock thenFold: [:acc :y | acc min: y]
     ]
     min [
         ^self collectThenMin: [:each | each]
     ]

     collectThenMax: collectBlock [
         ^self collect: collectBlock thenFold: [:acc :y | acc max: y]
     ]
     max [
         ^self collectThenMax: [:each | each]
     ]
]

CharacterArray extend [
     max: other [
       ^self < other ifTrue: [other] ifFalse: [self]
     ]

     min: other [
       ^self < other ifTrue: [self] ifFalse: [other]
     ]
]


Reply via email to