ව්‍යංජන වල වාසිය කුමක්ද?


162

මම ව්‍යංජන ගැන ඉගෙන ගත් අතර, මම සංකල්පය තේරුම් ගත්තා යැයි සිතන අතරම, එය භාවිතා කිරීමෙන් මට විශාල වාසියක් නොපෙනේ.

සුළු උදාහරණයක් ලෙස මම අගයන් දෙකක් එකතු කරන ශ්‍රිතයක් භාවිතා කරමි (එම්එල් හි ලියා ඇත). ව්‍යංජන නොමැතිව අනුවාදය වනු ඇත

fun add(x, y) = x + y

සහ ලෙස හැඳින්වේ

add(3, 5)

ව්‍යංජන අනුවාදය අතර

fun add x y = x + y 
(* short for val add = fn x => fn y=> x + y *)

සහ ලෙස හැඳින්වේ

add 3 5

එක් වරහන් වර්‍ගයක් ශ්‍රිතය නිර්වචනය කිරීමෙන් හා ඇමතීමෙන් ඉවත් කරන සින්ටැක්ටික් සීනි පමණක් බව මට පෙනේ. ව්‍යංජන ක්‍රියාකාරී භාෂාවක වැදගත් අංගයක් ලෙස ලැයිස්තුගත කර ඇති බව මම දැක ඇත්තෙමි, මේ මොහොතේ මම එය තරමක් යටපත් කර ඇත්තෙමි. ටියුපල් එකක් ගන්නා ශ්‍රිතයක් වෙනුවට එක් එක් පරාමිතියක් පරිභෝජනය කරන ශ්‍රිත දාමයක් නිර්මාණය කිරීමේ සංකල්පය සරල වාක්‍ය ඛණ්ඩයක් සඳහා භාවිතා කිරීම තරමක් සංකීර්ණ බව පෙනේ.

ව්‍යංජන සඳහා ඇති එකම අභිප්‍රේරණය තරමක් සරල වාක්‍ය ඛණ්ඩයක්ද, නැතහොත් මගේ ඉතා සරල උදාහරණයෙන් පැහැදිලි නොවන වෙනත් වාසි මට අහිමි වී තිබේද? ව්‍යංජන යනු සින්ටැක්ටික් සීනි පමණක්ද?


56
ව්‍යංජන පමණක් අත්යවශ්යයෙන්ම නිෂ් less ල ය, නමුත් සියලු කාර්යයන් පෙරනිමියෙන් ව්‍යංජන කර තිබීම වෙනත් අංග රාශියක් භාවිතා කිරීමට වඩා හොඳ කරයි. ඔබ ටික කලකට ක්‍රියාකාරී භාෂාවක් භාවිතා කරන තුරු මෙය අගය කිරීම අපහසුය.
සීඒ මැකාන්

4
ජොයෙල් ඊතර්ටන්ගේ පිළිතුර පිළිබඳ අදහස් දැක්වීමේදී ඩෙල්නන් පසුකර යාමේ සඳහන් කර ඇති දෙයක්, නමුත් මම පැහැදිලිවම සඳහන් කරනු ඇතැයි සිතුවෙමි, (අවම වශයෙන් හැස්කෙල්හිදී) ඔබට අර්ධ වශයෙන් අයදුම් කළ හැක්කේ කාර්යයන් පමණක් නොව, ඉදිකිරීම්කරුවන් ද ටයිප් කරන්න - මෙය තරමක් විය හැකිය හුරුබුහුටි; මෙය සිතා බැලිය යුතු දෙයක් විය හැකිය.
පෝල්

සියල්ලෝම හස්කල් පිළිබඳ උදාහරණ ලබා දී ඇත. ව්‍යංජන ප්‍රයෝජනවත් වන්නේ හස්කල්හි පමණක් යැයි කෙනෙකුට සිතිය හැකිය.
මනෝජ් ආර්

@ManojR සියලුම ඇත නොහැකි Haskell දී උදාහරණ ලබා දී ඇත.
phwd

1
මෙම ප්‍රශ්නය රෙඩ්ඩිට් පිළිබඳ තරමක් රසවත් සාකච්ඡාවක් ජනිත කළේය .
yannis

Answers:


130

ව්‍යංජන ශ්‍රිත සමඟින් ඔබ වඩාත් විශේෂ. වීමට පටන් ගන්නා බැවින් වඩාත් වියුක්ත කාර්යයන් නැවත භාවිතා කිරීම පහසු කරයි. ඔබට එකතු කිරීමේ ශ්‍රිතයක් ඇති බව කියමු

add x y = x + y

ලැයිස්තුවේ සෑම සාමාජිකයෙකුටම 2 ක් එක් කිරීමට ඔබට අවශ්‍ය බවත්. හැස්කෙල්හිදී ඔබ මෙය කරනු ඇත:

map (add 2) [1, 2, 3] -- gives [3, 4, 5]
-- actually one could just do: map (2+) [1, 2, 3], but that may be Haskell specific

මෙහිදී ඔබට ශ්‍රිතයක් නිර්මාණය කිරීමට වඩා වාක්‍ය ඛණ්ඩය සැහැල්ලු ය add2

add2 y = add 2 y
map add2 [1, 2, 3]

හෝ ඔබට නිර්නාමික ලැම්බඩා ශ්‍රිතයක් කිරීමට සිදු වූයේ නම්:

map (\y -> 2 + y) [1, 2, 3]

විවිධ ක්‍රියාත්මක කිරීම් වලින් වියුක්ත වීමට ද එය ඔබට ඉඩ සලසයි. අපි ඔබට බැලීමේ කාර්යයන් දෙකක් ඇති බව කියමු. එකක් යතුරු / අගය යුගල ලැයිස්තුවෙන් සහ අගයකට යතුරක් සහ තවත් සිතියමක සිට යතුරු සිට අගයන් දක්වා සහ අගයකට යතුරක්, මේ වගේ:

lookup1 :: [(Key, Value)] -> Key -> Value -- or perhaps it should be Maybe Value
lookup2 :: Map Key Value -> Key -> Value

එවිට ඔබට යතුරේ සිට අගය දක්වා බැලීමේ ශ්‍රිතයක් පිළිගත් ශ්‍රිතයක් කළ හැකිය. ඉහත සඳහන් ඕනෑම සෙවුම් ශ්‍රිතයක් ඔබට පිළිවෙලින් ලැයිස්තුවක් හෝ සිතියමක් සමඟ අර්ධ වශයෙන් යෙදිය හැකිය:

myFunc :: (Key -> Value) -> .....

අවසාන වශයෙන්: ව්‍යංජන හොඳයි, මන්ද එය ඔබට සැහැල්ලු වාක්‍ය ඛණ්ඩයක් භාවිතයෙන් කාර්යයන් විශේෂීකරණය කිරීමට / අර්ධ වශයෙන් යෙදීමට ඉඩ සලසයි, ඉන්පසු අර්ධ වශයෙන් යොදන ලද ශ්‍රිතයන් ඉහළ ඇණවුම් ශ්‍රිතයක් mapහෝ වැනි filter. ඉහළ ඇණවුම් කාර්යයන් (ඒවා පරාමිතීන් ලෙස ක්‍රියා කරයි හෝ ඒවා ප්‍රති results ල ලෙස ලබා දෙයි) යනු ක්‍රියාකාරී ක්‍රමලේඛනයේ පාන් සහ බටර් වන අතර ව්‍යංජන හා අර්ධ වශයෙන් යොදන කාර්යයන් මඟින් ඉහළ ඇණවුම් කාර්යයන් වඩාත් effectively ලදායී හා සංක්ෂිප්තව භාවිතා කිරීමට හැකි වේ.


32
මේ නිසා, හස්කල් හි කාර්යයන් සඳහා භාවිතා කරන තර්ක අනුපිළිවෙල බොහෝ විට පදනම් වී ඇත්තේ අර්ධ වශයෙන් යෙදිය හැකි ආකාරය මත වන අතර එමඟින් ඉහත විස්තර කර ඇති ප්‍රතිලාභ වැඩි අවස්ථාවන්හිදී (හෙක්, හෙක්) අදාළ වේ. පෙරනිමියෙන් ව්‍යංජන කිරීම මෙහි ඇති උදාහරණ වලින් පෙනෙන දෙයට වඩා ප්‍රයෝජනවත් වේ.
සීඒ මැකාන්

වොට්. "එකක් යතුරු / අගය යුගල ලැයිස්තුවෙන් සහ අගයකට යතුරක් සහ තවත් සිතියමක සිට යතුරු සිට අගයන් දක්වා සහ අගයකට යතුරක්"
මාටීන් උල්හාක්

AteMateenUlhaq එය පෙර වාක්‍යයේ අඛණ්ඩ පැවැත්මක් වන අතර, එහිදී යතුරක් මත පදනම්ව වටිනාකමක් ලබා ගැනීමට අපට අවශ්‍ය යැයි මම සිතමි, ඒ සඳහා අපට ක්‍රම දෙකක් තිබේ. වාක්‍යයෙන් එම ක්‍රම දෙක දක්වා ඇත. පළමු ආකාරයෙන්, ඔබට යතුරු / අගය යුගල ලැයිස්තුවක් සහ අපට වටිනාකම සොයා ගැනීමට අවශ්‍ය යතුර ලබා දී ඇති අතර, අනෙක් ආකාරයෙන් අපට නිසි සිතියමක් ලබා දී නැවත යතුරක් ලබා දෙනු ලැබේ. එය වාක්‍යයෙන් පසු වහාම කේතය දෙස බැලීමට උපකාරී වේ.
බොරිස්

54

ප්‍රායෝගික පිළිතුර නම් ව්‍යංජන මඟින් නිර්නාමික කාර්යයන් නිර්මාණය කිරීම වඩාත් පහසු වන බවයි. අවම ලැම්බඩා සින්ටැක්ස් සමඟ වුවද එය ජයග්‍රහණයකි. සංසන්දනය කරන්න:

map (add 1) [1..10]
map (\ x -> add 1 x) [1..10]

ඔබට කැත ලැම්බඩා සින්ටැක්ස් තිබේ නම් එය ඊටත් වඩා නරක ය. (මම ඔබ දෙස බලමි, ජාවාස්ක්‍රිප්ට්, යෝජනා ක්‍රමය සහ පයිතන්.)

ඔබ වැඩි වැඩියෙන් ඉහළ පෙළේ කාර්යයන් භාවිතා කරන බැවින් මෙය වැඩි වැඩියෙන් ප්‍රයෝජනවත් වේ. මම භාවිතා කරන අතර වැඩි වෙනත් භාෂා වඩා Haskell උසස් පෙළ කාර්යයන්, මම එක හොදයි මම ඇත්තටම ලැම්ඩා syntax එකක් භාවිතා සොයා අඩු නිසා කාලය තුනෙන් දෙකක් වගේ දෙයක්, මේ ලැම්ඩා හුදෙක් අර්ධ වශයෙන් ව්යවහාරික කාර්යය වනු ඇත. (අනෙක් බොහෝ වේලාවට මම එය නම් කරන ලද ශ්‍රිතයකට උපුටා ගනිමි.)

වඩාත් මූලික වශයෙන්, ශ්‍රිතයක කුමන අනුවාදය “කැනොනිකල්” ද යන්න සැමවිටම පැහැදිලි නැත. උදාහරණයක් ලෙස, ගන්න map. වර්ගය mapආකාර දෙකකින් ලිවිය හැකිය:

map :: (a -> b) -> [a] -> [b]
map :: (a -> b) -> ([a] -> [b])

"නිවැරදි" එක කුමක්ද? ඇත්තෙන්ම එය කීමට අපහසුය. ප්‍රායෝගිකව, බොහෝ භාෂාවන් පළමු එක භාවිතා කරයි - සිතියම ශ්‍රිතයක් සහ ලැයිස්තුවක් ගෙන ලැයිස්තුවක් ලබා දෙයි. කෙසේ වෙතත්, මූලික වශයෙන්, සිතියම සැබවින්ම කරන්නේ කාර්යයන් ලැයිස්තුගත කිරීම සඳහා සාමාන්‍ය කාර්යයන් සිතියම් ගත කිරීමයි - එය ශ්‍රිතයක් ගෙන ශ්‍රිතයක් ලබා දෙයි. සිතියම ව්‍යංජන නම්, ඔබට මෙම ප්‍රශ්නයට පිළිතුරු දිය යුතු නැත: එය දෙකම ඉතා අලංකාර ආකාරයකින් කරයි.

ඔබ mapලැයිස්තුව හැර වෙනත් වර්ග වලට සාමාන්‍යකරණය කළ පසු මෙය විශේෂයෙන් වැදගත් වේ.

ව්‍යංජන ඇත්තෙන්ම එතරම් සංකීර්ණ නොවේ. එය ඇත්ත වශයෙන්ම බොහෝ භාෂාවන් භාවිතා කරන ආකෘතියට වඩා සරල කිරීමකි: ඔබේ භාෂාවට පිළිස්සූ බහුවිධ තර්කවල කාර්යයන් පිළිබඳ කිසිදු අදහසක් ඔබට අවශ්‍ය නොවේ. මෙය යටින් පවතින ලැම්බඩා කැල්කියුලස් වඩාත් සමීපව පිළිබිඹු කරයි.

ඇත්ත වශයෙන්ම, එම්එල්-ශෛලියේ භාෂාවන්ට ව්‍යංජන හෝ නොකැඩූ ස්වරූපයෙන් බහුවිධ තර්ක පිළිබඳ අදහසක් නොමැත. මෙම f(a, b, c)කාරක රීති ඇත්තටම tuple දී පසුකර අනුරූප (a, b, c)බවට fනිසා, fතවමත් එකම තර්කය ගනී. මෙය ඇත්ත වශයෙන්ම ඉතා ප්‍රයෝජනවත් වෙනසක් වන අතර වෙනත් භාෂාවන්ට එය තිබිය හැකි යැයි මම සිතමි.

map f [(1,2,3), (4,5,6), (7, 8, 9)]

බහුවිධ තර්ක පිළිබඳ අදහස ඇති භාෂාවන් සමඟ ඔබට පහසුවෙන් මෙය කළ නොහැක!


1
“එම්එල්-ශෛලියේ භාෂාවන්ට ව්‍යංජන හෝ නොකැඩූ ස්වරූපයෙන් බහුවිධ තර්ක පිළිබඳ සංකල්පයක් නොමැත”: මේ සම්බන්ධයෙන්, හස්කල් එම්එල් විලාසිතාවද?
ජෝර්ජියෝ

1
ජෝර්ජියෝ: ඔව්.
ටිකොන් ජෙල්විස්

1
සිත්ගන්නා සුළුය. මම සමහර හස්කල් දන්නා අතර මම දැන් එස්එම්එල් ඉගෙන ගන්නෙමි, එබැවින් භාෂා දෙක අතර වෙනස්කම් හා සමානකම් දැකීම සිත්ගන්නා කරුණකි.
ජෝර්ජියෝ

හොඳ පිළිතුරක්, ඔබට තවමත් ඒත්තු ගැන්වීමට නොහැකි නම්
ලැම්බඩා ඇළට

"ප්‍රායෝගික" පිළිතුර එතරම් අදාළ නොවන්නේ වාචිකත්වය සාමාන්‍යයෙන් අර්ධ යෙදීමෙන් මග හැරෙන අතර ව්‍යංජන නොවේ. මම මෙහි තර්ක කරන්නේ ලැම්බඩා වියුක්ත කිරීමේ වාක්‍ය ඛණ්ඩය (වර්ගය ප්‍රකාශය නොතකා) යෝජනා ක්‍රමයට වඩා (අවම වශයෙන්) අවලස්සන බැවින් එය නිවැරදිව විග්‍රහ කිරීම සඳහා විශේෂිත සින්ටැක්ටික් නීති රීති අවශ්‍ය වන අතර එමඟින් භාෂා පිරිවිතර කිසිදු වාසියකින් තොරව පුපුරා යයි. අර්ථකථන ගුණාංග ගැන.
ෆ්‍රෑන්ක් එච් බී

24

ඔබ පළමු පන්තියේ වස්තුවක් ලෙස ගමන් කරන ශ්‍රිතයක් තිබේ නම් ව්‍යංජන ප්‍රයෝජනවත් විය හැකි අතර කේතයේ එක් ස්ථානයක එය ඇගයීමට අවශ්‍ය සියලු පරාමිතීන් ඔබට නොලැබේ. ඔබට පරාමිතීන් එකක් හෝ කිහිපයක් ලබා ගත් විට ඒවා සරලව යෙදිය හැකි අතර ප්‍රති result ලය තවත් පරාමිතීන් ඇති වෙනත් කේතයකට යැවිය හැකි අතර එය ඇගයීම අවසන් කරන්න.

මෙය සිදු කිරීම සඳහා වන කේතය ඔබට මුලින් සියලු පරාමිතීන් එකට ලබා ගැනීමට අවශ්‍ය නම් වඩා සරල වනු ඇත.

තනි පරාමිතියක් (තවත් ව්‍යංජන ශ්‍රිතයක්) ගන්නා කාර්යයන් සියලු පරාමිතීන් සමඟ විශේෂයෙන් ගැලපෙන්නේ නැති බැවින්, තවත් කේත නැවත භාවිතා කිරීමේ හැකියාව ඇත.


14

ව්‍යංජන සඳහා ප්‍රධාන පෙළඹවීම (අවම වශයෙන් මුලදී) ප්‍රායෝගික නොව න්‍යායාත්මක ය. විශේෂයෙන් ව්‍යංජන මඟින් බහු-තර්ක කාර්යයන් සැබවින්ම ලබා ගත හැකි අතර ඒවා සඳහා අර්ථකථන නිර්වචනය නොකර හෝ නිෂ්පාදන සඳහා අර්ථ නිරූපණය නොකරයි. මෙය වෙනත්, වඩා සංකීර්ණ භාෂාවක් තරම් ප්‍රකාශන සහිත සරල භාෂාවකට මඟ පෙන්වන අතර එය යෝග්‍ය වේ.


2
මෙහි අභිප්‍රේරණය න්‍යායාත්මක වුවත්, සරල බව සෑම විටම පාහේ ප්‍රායෝගික වාසියක් යැයි මම සිතමි. බහු තර්ක ක්‍රියාකාරිත්වයන් ගැන කරදර නොවීම, මම ක්‍රමලේඛනය කරන විට මගේ ජීවිතය පහසු කරයි, මම අර්ථ නිරූපණය සමඟ වැඩ කරන්නේ නම්.
ටිකොන් ජෙල්විස්

3
IkTikhonJelvis ඔබ ක්‍රමලේඛනය කරන විට, ව්‍යංජන මඟින් ඔබට කරදර වීමට වෙනත් දේ ලබා දේ, සම්පාදකයා ඔබ ශ්‍රිතයක් සඳහා තර්ක කිහිපයක් සම්මත කර ඇති බව හසු කර නොගැනීම හෝ එම අවස්ථාවේදී වැරදි දෝෂ පණිවිඩයක් ලබා ගැනීම වැනි; ඔබ ව්‍යංජන භාවිතා නොකරන විට, දෝෂය වඩාත් පැහැදිලිව පෙනේ.
ඇලෙක්ස් ආර්

මට කවදාවත් එවැනි ගැටළු ඇති වී නැත: GHC, අවම වශයෙන්, මේ සම්බන්ධයෙන් ඉතා හොඳයි. සම්පාදකයා සෑම විටම එවැනි ගැටලුවක් හසුකර ගන්නා අතර මෙම දෝෂය සඳහා හොඳ දෝෂ පණිවිඩ ද ඇත.
ටිකොන් ජෙල්විස්

1
දෝෂ පණිවිඩ හොඳ යැයි මට එකඟ විය නොහැක. සේවය කළ හැකි, ඔව්, නමුත් ඒවා තවමත් හොඳ නැත. එය දෝෂයක් ඇති වුවහොත් පමණක් එය එවැනි ගැටළුවක් ඇති කරයි, එනම් ඔබ පසුව ප්‍රති result ලය ශ්‍රිතයක් හැර වෙනත් දෙයක් ලෙස භාවිතා කිරීමට උත්සාහ කරන්නේ නම් (හෝ ඔබ විවරණය කර ඇත, නමුත් කියවිය හැකි දෝෂ සඳහා එය මත රඳා සිටීම එහි ගැටළු ඇත ); දෝෂය වාර්තා වූ ස්ථානය එහි සත්‍ය ස්ථානයෙන් දික්කසාද වී ඇත.
ඇලෙක්ස් ආර්

14

(මම හැස්කෙල්හි උදාහරණ දෙන්නම්.)

  1. ක්‍රියාකාරී භාෂාවන් භාවිතා කරන විට ඔබට අර්ධ වශයෙන් ශ්‍රිතයක් යෙදිය හැකිය. හස්කල් හි මෙන් , එහි තර්කය දී ඇති යෙදුමකට සමාන නම් (== x)නැවත පැමිණෙන ශ්‍රිතයකි :Truex

    mem :: Eq a => a -> [a] -> Bool
    mem x lst = any (== x) lst
    

    ව්‍යංජන නොකර, අපට කියවිය හැකි තරමක් අඩු කේතයක් ඇත:

    mem x lst = any (\y -> y == x) lst
    
  2. මෙය ටැසිට් ක්‍රමලේඛයට සම්බන්ධයි ( හස්කල් විකියේ පොයින්ට්ෆ්‍රී විලාසයද බලන්න ). මෙම ශෛලිය අවධානය යොමු කරන්නේ විචල්‍යයන් මගින් නිරූපණය වන අගයන් මත නොව, කාර්යයන් රචනා කිරීම සහ ශ්‍රිත දාමයක් හරහා තොරතුරු ගලා යන ආකාරය මත ය. අපගේ උදාහරණය විචල්‍යයන් භාවිතා නොකරන ආකාරයකට පරිවර්තනය කළ හැකිය:

    mem = any . (==)
    

    මෙහිදී අපි ==දකින්නේ සිට ශ්‍රිතයක් aලෙස a -> Boolසහ anyසිට ශ්‍රිතයක් ලෙස a -> Bool[a] -> Bool. ඒවා හුදෙක් රචනා කිරීමෙන් අපට ප්‍රති .ලය ලැබේ. මේ සියල්ල ව්‍යංජන වලට ස්තූතියි.

  3. ආපසු හැරවීම, ව්‍යංජන නොකිරීම සමහර අවස්ථාවලදී ප්‍රයෝජනවත් වේ. උදාහරණයක් ලෙස, අපට ලැයිස්තුවක් කොටස් දෙකකට බෙදීමට අවශ්‍ය යැයි කියමු - මූලද්‍රව්‍ය 10 ට වඩා කුඩා වන අතර අනෙක් ඒවා එම ලැයිස්තු දෙක සමඟ සංයුක්ත කරන්න. ලැයිස්තුව බෙදීම සිදු කරනු ලබන්නේ (මෙහි අපි ව්‍යංජන ද භාවිතා කරමු ). ප්රති result ලය වර්ගය වේ. එහි පළමු හා දෙවන කොටස බවට ප්රතිඵලයක් නිස්සාරණය හා භාවිතා ඔවුන් ඒකාබද්ධ වෙනුවට , අප uncurrying විසින් සෘජුවම මෙය කළ හැකි ලෙසpartition (< 10)<([Int],[Int])++++

    uncurry (++) . partition (< 10)
    

ඇත්ත වශයෙන්ම, (uncurry (++) . partition (< 10)) [4,12,11,1]ඇගයීමට ලක් කරයි [4,1,12,11].

වැදගත් න්‍යායාත්මක වාසි ද ඇත:

  1. දත්ත වර්ග නොමැති සහ ලැම්බඩා කැල්කියුලස් වැනි කාර්යයන් පමණක් ඇති භාෂාවන්ට ව්‍යංජන අත්‍යවශ්‍ය වේ . මෙම භාෂාවන් ප්‍රායෝගික භාවිතය සඳහා ප්‍රයෝජනවත් නොවන නමුත් න්‍යායාත්මක දෘෂ්ටි කෝණයකින් ඒවා ඉතා වැදගත් වේ.
  2. මෙය ක්‍රියාකාරී භාෂාවල අත්‍යවශ්‍ය දේපල සමඟ සම්බන්ධ වේ - කාර්යයන් පළමු පන්තියේ වස්තුවකි. අපි දැකලා තියෙනවා ලෙස, සිට පරිවර්තනය (a, b) -> cකිරීමට a -> (b -> c)අග කාර්යය කිරීමේ ප්රතිඵලයක් ආකාරයේ වන බව අදහස් b -> c. වෙනත් වචන වලින් කිවහොත්, ප්රති result ලය ශ්‍රිතයකි.
  3. (යූ) ව්‍යංජන කාටේෂියානු සංවෘත කාණ්ඩ සමඟ සමීපව සම්බන්ධ වී ඇති අතර එය ටයිප් කළ ලැම්බඩා කැල්කියුලි නැරඹීමේ නිශ්චිත ක්‍රමයකි.

“කියවිය හැකි තරම් අඩු කේතයක්” සඳහා, එය එසේ විය යුතු mem x lst = any (\y -> y == x) lstනොවේද? (බැක්ස්ලෑෂ් සමඟ).
stusmith

ඔව්, එය පෙන්වා දීමට ස්තූතියි, මම එය නිවැරදි කරමි.
පීටර් පුඩ්ලෙක්

9

ව්‍යංජන යනු සින්ටැක්ටික් සීනි පමණක් නොවේ!

add1(නොකැඩූ) සහ add2(ව්‍යංජන) වල අත්සන් සලකා බලන්න :

add1 : (int * int) -> int
add2 : int -> (int -> int)

(අවස්ථා දෙකේදීම, අත්සන වර්ගයේ වරහන් විකල්ප වේ, නමුත් පැහැදිලි කිරීම සඳහා මම ඒවා ඇතුළත් කර ඇත්තෙමි.)

add1ක 2-tuple ගත වන බව ශ්රිතයක් වේ intහා intහා නැවත පැමිණීමint . add2යනු ශ්‍රිතයක් වන අතර එය වෙනත් ශ්‍රිතයක්int නැවත ලබා දෙන අතර එය නැවත ලබා ගනී .intint

අප ක්‍රියාකාරී යෙදුම පැහැදිලිව සඳහන් කළ විට මේ දෙක අතර අත්‍යවශ්‍ය වෙනස වඩාත් දෘශ්‍යමාන වේ. එහි පළමු තර්කය එහි දෙවන තර්කයට අදාළ වන ශ්‍රිතයක් (ව්‍යංජන නොවේ) නිර්වචනය කරමු:

apply(f, b) = f b

දැන් අපට අතර වෙනස දැකිය හැකිය add1 සහ add2වඩාත් පැහැදිලිව. add12-ටුපල් සමඟ කැඳවනු ලැබේ:

apply(add1, (3, 5))

නමුත් එය add2සමඟ කැඳවනු ලබන int අතර එහි ප්‍රතිලාභ අගය තවත් එකක් සමඟ හැඳින්වේint :

apply(apply(add2, 3), 5)

සංස්කරණය කරන්න: ව්‍යංජන වල අත්‍යවශ්‍ය වාසිය නම් ඔබට අර්ධ වශයෙන් අයදුම්පත නොමිලේ ලබා ගැනීමයි. එහි පරාමිතියට 5 ක් එකතු කළ ආකාරයේ ශ්‍රිතයක් int -> int( mapලැයිස්තුවක් හරහා එයට කියන්න) ඔබට අවශ්‍ය යැයි කියමු . ඔබට ලිවිය හැකිය addFiveToParam x = x+5, නැතහොත් ඔබට ඉන්ලයින් ලැම්බඩා සමඟ සමාන දේ කළ හැකිය, නමුත් ඔබට වඩාත් පහසුවෙන් (විශේෂයෙන් මෙම අවස්ථාවන්ට වඩා සුළු කාරණා) ලිවිය හැකිය add2 5!


3
මගේ උදාහරණය සඳහා තිරය පිටුපස විශාල වෙනසක් ඇති බව මට වැටහී ඇත, නමුත් ප්‍රති result ලය සරල සින්ටැක්ටික් වෙනසක් ලෙස පෙනේ.
පිස්සු විද්‍යා ist

5
ව්‍යංජන යනු ඉතා ගැඹුරු සංකල්පයක් නොවේ. එය යටින් පවතින ආකෘතිය සරල කිරීම (ලැම්බඩා කැල්කියුලස් බලන්න) හෝ කෙසේ හෝ ටුපල් ඇති භාෂාවලින් එය ඇත්ත වශයෙන්ම අර්ධ යෙදුමේ සින්ටැක්ටික් පහසුව ගැන ය. සින්ටැක්ටික් පහසුවෙහි වැදගත්කම අවතක්සේරු නොකරන්න.
පීකර්

9

ව්‍යංජන යනු සින්ටැක්ටික් සීනි පමණි, නමුත් ඔබ සීනි කරන්නේ කුමක්ද යන්න තරමක් වරදවා වටහාගෙන ඇත, මම සිතමි. ඔබේ ආදර්ශය ගනිමින්,

fun add x y = x + y

ඇත්ත වශයෙන්ම සින්ටැක්ටිකල් සීනි වේ

fun add x = fn y => x + y

එනම්, (x එකතු කරන්න) y තර්කයක් ගෙන ශ්‍රිතයක් ලබා දෙන අතර x ට y එකතු කරයි.

fun addTuple (x, y) = x + y

එය ශ්‍රිතයක් වන අතර එය මූලද්‍රව්‍යයක් ගෙන එහි මූලද්‍රව්‍ය එකතු කරයි. එම කාර්යයන් දෙක සැබවින්ම බෙහෙවින් වෙනස් ය; ඔවුන් විවිධ තර්ක ගනී.

ලැයිස්තුවක ඇති සියලුම අංක වලට 2 ක් එකතු කිරීමට ඔබට අවශ්‍ය නම්:

(* add 2 to all numbers using the uncurried function *)
map (fn x => addTuple (x, 2)) [1,2,3]
(* using the curried function *)
map (add 2) [1,2,3]

ප්රති result ලය වනු ඇත [3,4,5].

ඔබට එක් එක් ටුපල් ලැයිස්තුවක් සාරාංශ කිරීමට අවශ්‍ය නම්, අනෙක් අතට, addTuple ශ්‍රිතය හොඳින් ගැලපේ.

(* Sum each tuple using the uncurried function *)
map addTuple [(10,2), (10,3), (10,4)]    
(* sum each tuple using curried function *)
map (fn (a,b) => add a b) [(10,2), (10,3), (10,4)]

ප්රති result ලය වනු ඇත [12,13,14].

අර්ධ යෙදුම ප්‍රයෝජනවත් වන විට ව්‍යංජන කාර්යයන් විශිෂ්ටයි - උදාහරණයක් ලෙස සිතියම, ගුණය, යෙදුම, පෙරණය. සපයන ලද ලැයිස්තුවේ විශාලතම ධනාත්මක අංකය ලබා දෙන මෙම ශ්‍රිතය සලකා බලන්න, නැතහොත් ධනාත්මක සංඛ්‍යා නොමැති නම් 0:

- val highestPositive = foldr Int.max 0;   
val highestPositive = fn : int list -> int 

1
ව්‍යංජන ශ්‍රිතයට වෙනත් ආකාරයේ අත්සනක් ඇති බවත් එය ඇත්ත වශයෙන්ම වෙනත් ශ්‍රිතයක් ලබා දෙන ශ්‍රිතයක් බවත් මම තේරුම් ගතිමි. අර්ධ යෙදුම් කොටස මට මග හැරී ඇත.
පිස්සු විද්‍යා

9

මා තවම සඳහන් කර නැති තවත් දෙයක් නම් ව්‍යංජන මගින් සාර්‍ථකතාවයට වඩා (සීමිත) වියුක්තයක් ලබා ගත හැකි බවයි.

හස්කල්ගේ පුස්තකාලයේ කොටසක් වන මෙම කාර්යයන් සලකා බලන්න

(.) :: (b -> c) -> (a -> b) -> a -> c
either :: (a -> c) -> (b -> c) -> Either a b -> c
flip :: (a -> b -> c) -> b -> a -> c
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c

සෑම අවස්ථාවකම වර්ග විචල්‍යය cශ්‍රිත වර්ගයක් විය හැකි අතර එමඟින් මෙම ශ්‍රිත ඒවායේ පරාමිති ලැයිස්තුවේ යම් උපසර්ගයක් මත ක්‍රියා කරයි. ව්‍යංජන නොමැතිව, ශ්‍රිත විචල්‍යතාවයට වඩා වියුක්ත කිරීමට ඔබට විශේෂ භාෂා අංගයක් අවශ්‍ය වනු ඇත හෝ විවිධ ප්‍රභේද සඳහා විශේෂිත වූ මෙම ශ්‍රිතවල විවිධ අනුවාදයන් තිබිය යුතුය.


6

මගේ සීමිත අවබෝධය එවැනි ය:

1) අර්ධ ක්‍රියාකාරී යෙදුම

අර්ධ ශ්‍රිත යෙදුම යනු අඩු තර්ක සංඛ්‍යාවක් ගන්නා ශ්‍රිතයක් නැවත ලබා දීමේ ක්‍රියාවලියයි. ඔබ තර්ක 3 න් 2 ක් සපයන්නේ නම්, එය 3-2 = 1 පරාමිතියක් ගන්නා ශ්‍රිතයක් නැවත ලබා දෙනු ඇත. ඔබ තර්ක 3 න් 1 ක් ලබා දෙන්නේ නම්, එය තර්ක 3-1 = 2 ක් ගන්නා ශ්‍රිතයක් නැවත ලබා දෙනු ඇත. ඔබට අවශ්‍ය නම්, ඔබට තර්ක 3 න් 3 ක් අර්ධ වශයෙන් යෙදිය හැකි අතර එය කිසිදු තර්කයක් නොගන්නා ශ්‍රිතයක් නැවත ලබා දෙනු ඇත.

එබැවින් පහත සඳහන් ශ්‍රිතය ලබා දී ඇත:

f(x,y,z) = x + y + z;

1 සිට x දක්වා බන්ධනය වන විට සහ ඉහත ශ්‍රිතයට එය අර්ධ වශයෙන් යොදන විට f(x,y,z)ඔබට ලැබෙනුයේ:

f(1,y,z) = f'(y,z);

කොහෙද: f'(y,z) = 1 + y + z;

දැන් ඔබ y සිට 2 දක්වා සහ z සිට 3 දක්වා බන්ධනය කර අර්ධ වශයෙන් අයදුම් f'(y,z)කරන්නේ නම් ඔබට ලැබෙනු ඇත:

f'(2,3) = f''();

කොහෙද : f''() = 1 + 2 + 3;

දැන් ඕනෑම අවස්ථාවක, ඔබට ඇගයීමට තෝරා ගත හැකිය f, f'හෝ f''. එබැවින් මට කළ හැකිය:

print(f''()) // and it would return 6;

හෝ

print(f'(1,1)) // and it would return 3;

2) කරිං

අනෙක් අතට ව්‍යංජන යනු ශ්‍රිතයක් එක් තර්ක ශ්‍රිතයක කැදැලි දාමයකට බෙදීමේ ක්‍රියාවලියයි. ඔබට කිසි විටෙකත් තර්ක 1 කට වඩා ලබා දිය නොහැක, එය එකක් හෝ බිංදුවකි.

එබැවින් එකම ශ්‍රිතයක් ලබා දී ඇත:

f(x,y,z) = x + y + z;

ඔබ එය ව්‍යංජන කළහොත් ඔබට කාර්යයන් 3 ක දාමයක් ලැබෙනු ඇත:

f'(x) -> f''(y) -> f'''(z)

කොහෙද:

f'(x) = x + f''(y);

f''(y) = y + f'''(z);

f'''(z) = z;

දැන් ඔබට කතා නම් f'(x)සමග x = 1:

f'(1) = 1 + f''(y);

ඔබට නව කාර්යයක් ලබා දෙනු ලැබේ:

g(y) = 1 + f''(y);

ඔබ අමතන්නේ නම් g(y)සමග y = 2:

g(2) = 1 + 2 + f'''(z);

ඔබට නව කාර්යයක් ලබා දෙනු ලැබේ:

h(z) = 1 + 2 + f'''(z);

අවසාන වශයෙන් ඔබ කියන්නේ නම්, h(z)සමග z = 3:

h(3) = 1 + 2 + 3;

ඔබ ආපසු එනු 6ලැබේ.

3) වසා දැමීම

අවසාන වශයෙන්, වසා දැමීම යනු ශ්‍රිතයක් සහ දත්ත එක් ඒකකයක් ලෙස ග්‍රහණය කර ගැනීමේ ක්‍රියාවලියයි. ශ්‍රිතයක් වැසීම සඳහා අසීමිත තර්ක ගණනකට 0 ක් ගතවනු ඇත, නමුත් එය වෙත නොපැමිණෙන දත්ත පිළිබඳව ද එය දැන සිටියි.

නැවතත්, එකම ශ්‍රිතයක් ලබා දී ඇත:

f(x,y,z) = x + y + z;

ඔබට ඒ වෙනුවට වසා දැමීමක් ලිවිය හැකිය:

f(x) = x + f'(y, z);

කොහෙද:

f'(y,z) = x + y + z;

f'වසා ඇත x. f'ඇතුළත ඇති x හි අගය කියවිය හැකි අර්ථය f.

එසේ නම් ඔබ ඇමතීමට සිටි fසමග x = 1:

f(1) = 1 + f'(y, z);

ඔබට වසා දැමීමක් ලැබෙනු ඇත:

closureOfF(y, z) =
                   var x = 1;
                   f'(y, z);

දැන් ඔබ කැඳවා නම් closureOfFසමග y = 2හා z = 3:

closureOfF(2, 3) = 
                   var x = 1;
                   x + 2 + 3;

එය නැවත පැමිණේ 6

නිගමනය

ව්‍යංජන, අර්ධ යෙදුම සහ වසා දැමීම් සියල්ලම තරමක් සමාන වන අතර ඒවා ශ්‍රිතයක් තවත් කොටස් වලට දිරාපත් කරයි.

ව්‍යංජන මඟින් තනි තර්කවල ශ්‍රිත නැවත ලබා දෙන තනි තර්කවල කැදැලි ශ්‍රිත බවට බහුවිධ තර්කවල ශ්‍රිතයක් දිරාපත් වේ. එක් හෝ අඩු තර්කයක ශ්‍රිතයක් ව්‍යංජන කිරීමෙන් කිසිදු තේරුමක් නැත.

අර්ධ යෙදුම මඟින් බහු තර්ක වල ශ්‍රිතයක් අඩු තර්ක වල ශ්‍රිතයක් බවට දිරාපත් වන අතර ඒවායේ දැන් නැතිවී ඇති තර්ක සැපයූ අගය සඳහා ආදේශ කර ඇත.

වසා දැමීම ශ්‍රිතයක් ශ්‍රිතයක් ලෙස දිරාපත් වන අතර දත්ත සමුදායක් තුළට නොපැමිණෙන ශ්‍රිතයේ විචල්‍යයන් ඇගයීමට ලක් කළ විට ඊට එරෙහිව බැඳීමට අගයක් සොයා ගත හැකිය.

මේ සියල්ල අවුල් සහගත කාරණය නම්, අනෙක් ඒවා අනු කාණ්ඩයක් ක්‍රියාත්මක කිරීම සඳහා එක් එක් වර්ගයට යොදා ගත හැකි වීමයි. එබැවින් සාරාංශයක් ලෙස, ඒවා සියල්ලම ක්‍රියාත්මක කිරීමේ විස්තරයකි. ඒවා සියල්ලම සමාන අගයක් ලබා දෙන අතර එමඟින් ඔබට සියලු අගයන් පෙරට ගෙන ඒමට අවශ්‍ය නොවන අතර එමඟින් ඔබ ශ්‍රිතයේ කොටසක් නැවත භාවිතා කළ හැකිය.

අනාවරණය

මම කිසිසේත් මාතෘකාව පිළිබඳ විශේෂ expert යෙක් නොවෙමි, මම මෑතකදී මේවා ගැන ඉගෙන ගැනීමට පටන් ගෙන ඇත්තෙමි, එබැවින් මම මගේ වර්තමාන අවබෝධය ලබා දෙමි, නමුත් එය පෙන්වා දීමට මා ඔබට ආරාධනා කරන වැරදි තිබිය හැකි අතර, මම / ලෙස නිවැරදි කරමි මම ඕනෑම දෙයක් සොයා ගතිමි.


1
ඉතින් පිළිතුර: ව්‍යංජන කිරීමෙන් වාසියක් නැද්ද?
ceving

1
මම දන්නා තරමින් එය නිවැරදිය. ප්‍රායෝගිකව ව්‍යංජන හා අර්ධ යෙදුම් ඔබට එකම ප්‍රතිලාභ ලබා දෙනු ඇත. භාෂාවක ක්‍රියාත්මක කළ යුතු තේරීම ක්‍රියාත්මක කිරීමේ හේතූන් මත සිදු කර ඇති අතර, එකක් ක්‍රියාත්මක කිරීමට පහසු විය හැකි අතර තවත් භාෂාවක් ලබා දී ඇත.
ඩිඩියර් ඒ.

5

ව්‍යංජන (අර්ධ යෙදුම) සමහර පරාමිතීන් සවි කිරීමෙන් පවතින ශ්‍රිතයකින් නව ශ්‍රිතයක් නිර්මාණය කිරීමට ඔබට ඉඩ සලසයි. එය ශබ්දකෝෂ වැසීමේ විශේෂ අවස්ථාවකි, එහිදී නිර්නාමික ශ්‍රිතය සුළු සුළු ආවරණයක් වන අතර එය අල්ලා ගත් තර්ක වෙනත් ශ්‍රිතයකට යොමු කරයි. ශබ්දකෝෂ වැසීම සඳහා සාමාන්‍ය සින්ටැක්ස් භාවිතා කිරීමෙන් අපට මෙය කළ හැකි නමුත් අර්ධ යෙදුම මඟින් සරල කරන ලද සින්ටැක්ටික් සීනි සපයයි.

Lisp ක්‍රමලේඛකයින්, ක්‍රියාකාරී ශෛලියක් තුළ වැඩ කරන විට, සමහර විට අර්ධ යෙදුම් සඳහා පුස්තකාල භාවිතා කරයි .

(lambda (x) (+ 3 x))එහි තර්කයට 3 ​​ක් එකතු කරන ශ්‍රිතයක් අපට ලබා දෙනවා වෙනුවට , ඔබට එවැනි දෙයක් ලිවිය හැකිය (op + 3), එබැවින් යම් ලැයිස්තුවක සෑම මූලද්‍රව්‍යයකටම 3 ක් එකතු කිරීම (mapcar (op + 3) some-list)වෙනුවට වනු ඇත (mapcar (lambda (x) (+ 3 x)) some-list). මෙම opසාර්ව මඟින් ඔබට යම් තර්ක විතර්ක x y z ...ගෙන ආයාචනා කරන ශ්‍රිතයක් බවට පත් කරනු ඇත (+ a x y z ...).

බොහෝ තනිකරම ක්‍රියාකාරී භාෂාවල, opක්‍රියාකරුවෙකු නොමැති වන පරිදි අර්ධ යෙදුම සින්ටැක්ස් තුළට ඇතුළත් කර ඇත . අර්ධ යෙදුම අවුලුවාලීමට, ඔබ අවශ්‍ය වන්නේ ඊට වඩා අඩු තර්ක සහිත ශ්‍රිතයක් අමතන්න. "insufficient number of arguments"දෝෂයක් ඇති කරනවා වෙනුවට, ප්‍රති result ලය ඉතිරි තර්කවල ශ්‍රිතයකි.


"ව්‍යංජන ... ඔබට නව ශ්‍රිතයක් නිර්මාණය කිරීමට ඉඩ දෙයි ... සමහර පරාමිතීන් සවි කිරීමෙන්" - නැත, වර්ගයක ශ්‍රිතයකට a -> b -> cපරාමිති s (බහු) නොමැත, එයට ඇත්තේ එක් පරාමිතියක් පමණි , c. ඇමතූ විට, එය වර්ගයේ ශ්‍රිතයක් ලබා දෙයි a -> b.
මැක්ස් හයිබර්

4

කාර්යය සඳහා

fun add(x, y) = x + y

එය ස්වරූපයෙන් වේ f': 'a * 'b -> 'c

එකක් ඇගයීමට ලක් කරනු ඇත

add(3, 5)
val it = 8 : int

ව්‍යංජන කාර්යය සඳහා

fun add x y = x + y

එකක් ඇගයීමට ලක් කරනු ඇත

add 3
val it = fn : int -> int

එය අර්ධ ගණනය කිරීමක් වන විට, විශේෂයෙන් (3 + y), එවිට කෙනෙකුට ගණනය කිරීම සම්පූර්ණ කළ හැකිය

it 5
val it = 8 : int

දෙවන අවස්ථාවෙහි එකතු කිරීම ස්වරූපයෙන් වේ f: 'a -> 'b -> 'c

මෙහි ව්‍යංජන කරන්නේ ගිවිසුම් දෙකක් ගන්නා ශ්‍රිතයක් එකක් බවට පරිවර්තනය කිරීම ප්‍රති one ලයක් නැවත ලබා ගැනීම පමණි. අර්ධ ඇගයීම

කෙනෙකුට මෙය අවශ්‍ය වන්නේ ඇයි?

ආර්එච්එස් xගැන කියන්න සාමාන්‍ය ඉන්ටර් එකක් නොවේ, ඒ වෙනුවට සංකීර්ණ ගණනය කිරීමක් සම්පූර්ණ කිරීමට ටික කාලයක් ගතවේ, වැඩි දියුණු කිරීම් සඳහා, තත්පර දෙකක්.

x = twoSecondsComputation(z)

ඉතින් දැන් ශ්‍රිතය වගේ

fun add (z:int) (y:int) : int =
    let
        val x = twoSecondsComputation(z)
    in
        x + y
    end;

වර්ගය add : int * int -> int

දැන් අපට මෙම ශ්‍රිතය සංඛ්‍යා පරාසයක් සඳහා ගණනය කිරීමට අවශ්‍යය, එය සිතියම් ගත කරමු

val result1 = map (fn x => add (20, x)) [3, 5, 7];

ඉහත සඳහා ප්‍රති result twoSecondsComputationලය සෑම අවස්ථාවකම ඇගයීමට ලක් කෙරේ. මෙයින් අදහස් කරන්නේ මෙම ගණනය කිරීම සඳහා තත්පර 6 ක් ගත වන බවයි.

වේදිකා ගත කිරීම සහ ව්‍යංජන කිරීම වැනි දේ භාවිතා කිරීමෙන් මෙය වළක්වා ගත හැකිය.

fun add (z:int) : int -> int =
    let
        val x = twoSecondsComputation(z)
    in
        (fn y => x + y)
    end;

ව්‍යංජන ස්වරූපයෙන් add : int -> int -> int

දැන් කෙනෙකුට කරන්න පුළුවන්,

val add' = add 20;
val result2 = map add' [3, 5, 7, 11, 13];

මෙම twoSecondsComputationඑක් වරක් ඇගයීමට ලක් කළ පමණක් අවශ්ය වේ. පරිමාණය ඉහළ නැංවීම සඳහා තත්පර දෙකක් මිනිත්තු 15 ක් හෝ ඕනෑම පැයක් වෙනුවට ආදේශ කරන්න, ඉන්පසු අංක 100 ට එරෙහිව සිතියමක් තබා ගන්න.

සාරාංශය : අර්ධ ඇගයීමේ මෙවලමක් ලෙස ඉහළ මට්ටමේ කාර්යයන් සඳහා වෙනත් ක්‍රම භාවිතා කරන විට ව්‍යංජන විශිෂ්ටයි. එහි අරමුණ සැබවින්ම තනිවම පෙන්විය නොහැක.


3

ව්‍යංජන නම්යශීලී ක්‍රියාකාරී සංයුතියට ඉඩ දෙයි.

මම "ව්‍යංජන" ශ්‍රිතයක් හැදුවා. මෙම සන්දර්භය තුළ, මට කුමන ආකාරයේ ල ger ු-සටහනක් ලැබේද යන්න හෝ එය පැමිණෙන්නේ කොතැනින්ද යන්න මට ප්‍රශ්නයක් නොවේ. ක්‍රියාව කුමක්ද හෝ එය පැමිණෙන්නේ කොතැනින්ද යන්න මට ප්‍රශ්නයක් නොවේ. මම සැලකිලිමත් වන්නේ මගේ ආදානය සැකසීම පමණි.

var builder = curry(function(input, logger, action) {
     logger.log("Starting action");
     try {
         action(input);
         logger.log("Success!");
     }
     catch (err) {
         logger.logerror("Boo we failed..", err);
     }
});
var x = "My input.";
goGatherArgs(builder)(x); // Supplies action first, then logger somewhere.

බිල්ඩර් විචල්‍යය යනු මගේ ශ්‍රිතය කරන මගේ ආදානය ගන්නා ශ්‍රිතයක් නැවත ලබා දෙන ශ්‍රිතයකි. මෙය සරල ප්‍රයෝජනවත් උදාහරණයකි.


2

ශ්‍රිතයක් සඳහා ඔබට සියලු තර්ක නොමැති විට ව්‍යංජන යනු වාසියකි. ඔබ ශ්‍රිතය සම්පූර්ණයෙන් තක්සේරු කරන්නේ නම්, සැලකිය යුතු වෙනසක් නොමැත.

ව්‍යංජන මඟින් ඔබට තවමත් අවශ්‍ය නොවන පරාමිතීන් සඳහන් කිරීමෙන් වළක්වා ගත හැකිය. එය වඩාත් සංක්ෂිප්ත වන අතර, පරාසයේ වෙනත් විචල්‍යයක් සමඟ ගැටෙන්නේ නැති පරාමිති නාමයක් සොයා ගැනීම අවශ්‍ය නොවේ (එය මගේ ප්‍රියතම වාසියයි).

නිදසුනක් ලෙස, ශ්‍රිතයන් තර්ක ලෙස ගෙන යන ශ්‍රිත භාවිතා කරන විට, ඔබට බොහෝ විට "ආදානය සඳහා 3 එකතු කරන්න" හෝ "ආදාන විචල්ය v සමඟ සංසන්දනය කරන්න" වැනි කාර්යයන් අවශ්‍ය අවස්ථාවන්හිදී ඔබ සොයා ගනු ඇත. ව්‍යංජන සමඟ, මෙම කාර්යයන් පහසුවෙන් ලිවිය හැකිය: add 3සහ (== v). ව්‍යංජන නොමැතිව, ඔබට ලැම්බඩා ප්‍රකාශන භාවිතා කළ යුතුය: x => add 3 xසහ x => x == v. මෙම ලැම්ඩා ප්රකාශන මෙන් දෙගුණයක් වන අතර, අමතරව නමක් තෝරා අදාල කාර්ය බහුල වැඩ කුඩා ප්රමාණයක් ඇති xවූ එහි දැනටමත් වේ නම් xවිෂය පථය තුල.

ව්‍යංජන මත පදනම් වූ භාෂාවන්හි අතුරු ප්‍රතිලාභයක් නම්, කාර්යයන් සඳහා සාමාන්‍ය කේත ලිවීමේදී, පරාමිති ගණන මත පදනම්ව ඔබ සිය ගණනක් ප්‍රභේද සමඟ අවසන් නොවේ. උදාහරණයක් ලෙස, C # හි, 'ව්‍යංජන' ක්‍රමයකට Func <R>, Func <A, R>, Func <A1, A2, R>, Func <A1, A2, A3, R> යනාදිය සඳහා ප්‍රභේද අවශ්‍ය වේ. සදහටම. හස්කල් හි, Func <A1, A2, R> ට සමාන වන්නේ Func <Tuple <A1, A2>, R> හෝ Func <A1, Func <A2, R >> (සහ Func <R> එය වඩාත් Func <Unit, R> වැනි ය, එබැවින් සියලු ප්‍රභේද තනි Func <A, R> නඩුවට අනුරූප වේ.


2

මට සිතිය හැකි මූලික තර්කය (මම කිසිසේත් මෙම විෂය පිළිබඳ විශේෂ expert යෙක් නොවෙමි) එහි කාර්යයන් සුළුපටු සිට සුළු නොවන දක්වා ගමන් කරන විට එහි ප්‍රතිලාභ පෙන්වීමට පටන් ගනී. මේ ආකාරයේ බොහෝ සංකල්ප ඇති සියලු සුළු කාරණාවලදී ඔබට සැබෑ ප්‍රතිලාභයක් නොලැබෙනු ඇත. කෙසේ වෙතත්, බොහෝ ක්‍රියාකාරී භාෂා සැකසුම් මෙහෙයුම් වලදී තොගය අධික ලෙස භාවිතා කරයි. මේ සඳහා උදාහරණ ලෙස PostScript හෝ Lisp සලකා බලන්න . ව්‍යංජන භාවිතා කිරීමෙන්, කාර්යයන් වඩාත් effectively ලදායී ලෙස ගොඩගැසිය හැකි අතර, මෙහෙයුම් අඩු හා අඩු වශයෙන් වර්ධනය වන විට මෙම ප්‍රතිලාභය පැහැදිලි වේ. ව්‍යංජන ආකාරයෙන්, විධානය සහ තර්ක පිළිවෙලට තොගයට විසි කර අවශ්‍ය පරිදි පිටතට ගෙන යා හැකි බැවින් ඒවා නිසි පිළිවෙළට ක්‍රියාත්මක වේ.


1
තව බොහෝ රාමු සෑදීම අවශ්‍ය වීමෙන් දේවල් වඩාත් කාර්යක්ෂම වන්නේ කෙසේද?
මේසන් රෝද

1
Ason මේසන් වීලර්: මම ක්‍රියාකාරී භාෂා හෝ ව්‍යංජන පිළිබඳ විශේෂ expert යෙක් නොවන බව මා කී පරිදි මම නොදනිමි. මම විශේෂයෙන් මෙම ප්‍රජා විකිය ලේබල් කළේ ඒ නිසාය.
ජොයෙල් ඊතර්ටන්

4
AsonMasonWheeler ඔබට මෙම පිළිතුරේ වාක්‍ය ඛණ්ඩනය කිරීමේ ලක්ෂ්‍යයක් ඇත, නමුත් මට සිතා බැලීමට ඉඩ දෙන්න, ඇත්ත වශයෙන්ම නිර්මාණය කරන ලද රාමු ප්‍රමාණය ක්‍රියාත්මක කිරීම මත බොහෝ සෙයින් රඳා පවතී. නිදසුනක් ලෙස, කොඳු ඇට පෙළ රහිත ටැග්ලස් ජී යන්ත්‍රයේ (එස්ටීජී; ජීඑච්සී විසින් හස්කල් ක්‍රියාත්මක කරන ආකාරය) සියලු (හෝ අවම වශයෙන් අවශ්‍ය යැයි දන්නා තරමට) තර්ක එකතු කරන තෙක් සත්‍ය ඇගයීම ප්‍රමාද කරයි. මෙය සිදු කර ඇත්තේ සියලුම කාර්යයන් සඳහාද නැතිනම් ඉදිකිරීම්කරුවන් සඳහාද යන්න මට මතක නැත, නමුත් බොහෝ කාර්යයන් සඳහා එය කළ හැකි යැයි මම සිතමි . (ඉන්පසු නැවතත්, "රාමු රාමු" යන සංකල්පය STG වලට සැබවින්ම අදාළ නොවේ.)

1

ව්‍යංජන රඳා පවතින්නේ ශ්‍රිතයක් නැවත ලබා දීමේ හැකියාව මත ය.

මෙම (ව්‍යාජ) ව්‍යාජ කේතය සලකා බලන්න.

var f = (m, x, b) => ... යමක් ආපසු එවන්න ...

තර්ක තුනකට වඩා අඩු සංඛ්‍යාවක් සහිත f ඇමතීමෙන් ශ්‍රිතයක් ලැබෙන බව අපි නියම කරමු.

var g = f (0, 1); // මෙය තවත් තර්කයක් (ආ) පිළිගන්නා 0 සහ 1 (m සහ x) වලට බැඳී ඇති ශ්‍රිතයක් ලබා දෙයි.

var y = g (42); m සහ x සඳහා 0 සහ 1 භාවිතා කරමින්, නැතිවූ තෙවන තර්කය සමඟ g ආයාචනා කරන්න

ඔබට අර්ධ වශයෙන් තර්ක යෙදිය හැකි අතර නැවත භාවිතා කළ හැකි ශ්‍රිතයක් නැවත ලබා ගත හැකිය (ඔබ සැපයූ එම තර්ක වලට බැඳී) තරමක් ප්‍රයෝජනවත් වේ (සහ DRY).

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.