Hullas biz ishlatadigan database libraryda db entitiylar quyidagicha tipda bo'ladi
Entity Key Valdata Entity record =
Entity { entityKey :: Key record
, Entity record -> record
entityVal :: record }
Database call uchun esa library boshqa ORMlar kabi methodlar taqdim qiladi, masalan
get, insert vaxakazo.Masalan sizda User va Post degan entitylar bo'lsa ikkisiga ham bemalol
get yoki getEntity ishlata olasiz. Lekin bu narsani harsafar qo'lda yozib yurish kerak. Masalan get :: (AppState, MonadIO m) => UserId -> m (Maybe (Entity User))
get i = withPool $ DB.getEntity i
get :: (AppState, MonadIO m) => PostId -> m (Maybe (Entity Post))
get i = withPool $ DB.getEntity i
Codega etibor qilsangiz buyoqda faqat tiplar farq qilyabti. Qolgani birxil. Bu narsa ortiqcha code degani.
A manda esa boshqa ideya paydo bo'ldi. Bizda faqat tiplar farq qilyabti ekan, nima uchun biz funksiyaga aynan qaysi tipga ishlashi kerakligini tashqaridan aytmaslik kerak ?
Haskellda bu narsani qilsa bo'ladi
RequiredTypeArguments bilan. Yani getById funksiya yozamiz va funksiyamiz id parametridan tashqari yana bitta argument qabul qiladi, bu argument esa tip, yani biz funksiya qaysi tip ekaniga qarab ishlaydi.Shunda biz
getById (type Entity User) i qilib userni get qilishni agar bizga post kerak bo'lsa unda type (Entity Post) berib post entitydan get qilishni amalga oshira olamiz. Endi harsafar bir funksiyani turli tipga qo'lda yozmaymiz balki bitta funksiyani aynan berilgan tipga qarab ishlaydigan qilamiz va qaysi tip bilan ishlashi esa argumentda beriladi.
Rasmda full implementation va bu kecha qilindi, endi common primitivlarni manashunday qilib chiqishni boshladim
get, select, insert.
