Haskellã§è§£ãã®ã楽ãªåé¡ããã£ã¦Haskellã§æ¸ãããã©ããã®å¾iOSã¢ããªãã使ããããªã£ãã®ã§èª¿ã¹ã¦ã¿ãã
GHC iOS ã®å°å ¥
ã¾ããGHCãcabal-installãææ°ã«ãã¦ããã
brew install ghc cabal-install cabal update && cabal install cabal-install
~/.cabal/config ã« $ncups
ã¨ããå®ç¾©ããã£ããæ¶ãå¿
è¦ãããããããããã¡ã«ã¯ãªãã£ãã
ghc-ios-scriptsãcloneãã¦ãã¹ãéãã
git clone [email protected]:ghc-ios/ghc-ios-scripts.git ~/bin/ghc-ios-scripts echo -e "\nPATH=~/bin/ghc-ios-scripts:"'$PATH' >> ~/.profile PATH=~/bin/ghc-ios-scripts:$PATH
installGHCiOS.shãå®è¡ãã¯ãã¹ã³ã³ãã¤ã«ç¨ã®GHCã¨ããå ¥ãã¦ãããã
installGHCiOS.sh
ããã³ã±ãã®ã§èª¿ã¹ã¦ã¿ãããcurlããªãã¤ã¬ã¯ãå¦çãã¦ãªãã£ãã®ã§ä¿®æ£ãå度å®è¡ããããããã
diff --git a/installGHCiOS.sh b/installGHCiOS.sh index e13087e..780c326 100755 --- a/installGHCiOS.sh +++ b/installGHCiOS.sh @@ -13,7 +13,7 @@ fi echo "Downloading GHC for iOS devices..." -curl -O https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-arm-apple-ios.tar.xz +curl -OL https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-arm-apple-ios.tar.xz tar xvf ghc-7.8.3-arm-apple-ios.tar.xz && mv ghc-7.8.3 ghc-7.8.3-arm rm ghc-7.8.3-arm-apple-ios.tar.xz cd ghc-7.8.3-arm @@ -35,7 +35,7 @@ rm -r ghc-7.8.3-arm echo "Downloading GHC for the iOS simulator..." cd /tmp -curl -O https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-i386-apple-ios.tar.xz +curl -OL https://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-i386-apple-ios.tar.xz tar xvf ghc-7.8.3-i386-apple-ios.tar.xz && mv ghc-7.8.3 ghc-7.8.3-i386 rm ghc-7.8.3-i386-apple-ios.tar.xz cd ghc-7.8.3-i386
iOSã¢ããªããã¸ã§ã¯ãä½æ
Xcodeã§æ°è¦ããã¸ã§ã¯ããä½ãã
CocoaPodsã¨å調å©ç¨ã§ããã確èªãããã£ãããã¨ããããé©å½ã«1ã¤å ¥ãã¦ããã
platform :ios, '8.0' pod 'SDWebImage' use_frameworks!
HaskelliOS.xcconfigããã¦ã³ãã¼ããã¦ããã¸ã§ã¯ãã«è¿½å ãããã¨CocoaPodsã®xcconfigããã¼ã¸ããxcconfigãä½æãã¦ãåãå ãCocoaPodsã®ãã®ãããã¡ãã«åããã
#include "Pods/Target Support Files/Pods/Pods.debug.xcconfig" #include "HaskelliOS.xcconfig"
#include "Pods/Target Support Files/Pods/Pods.release.xcconfig" #include "HaskelliOS.xcconfig"
HaskelliOS.xcconfigã®ARCHS = "$(ARCHS_STANDARD_32_BIT)"
ã®ã³ã¡ã³ãã¢ã¦ããå¤ã(ã¾ã 64bitã§åããªã)ãã¾ããHEADER_SEARCH_PATHSãèªåã®ç°å¢ã«åããã¦æ¸ãç´ãããã¡ã®ç°å¢ã§ã¯ãã¼ã¸ã§ã³ã ããªãããã
ã½ã¼ã¹ã³ã¼ãã®é ç½®
ã¢ããªã®ã³ã¼ãã®ä¸ã«Haskellã¨ãããã©ã«ããä½ã£ã¦ãhaskell.hsã追å ã試ãã«ä»¥ä¸ã®ãããªã³ã¼ããæ¸ããæ»ãå¤ã¯IOã§ãããå¿ è¦ãããæ§åã
{-# LANGUAGE ForeignFunctionInterface #-} module HTestApp where import Foreign foreign export ccall x3Int :: Int -> IO Int x3Int :: Int -> IO Int x3Int x = return $ x * 3!
ãã®ç¶æ
ã§ãghc-ios haskell.hs
ããã«ãããã¨.aã¨ã.hã¨ãåºã¦ããã®ã§ãHaskellãã©ã«ããã¨ã¾ãã£ã¨ããã¸ã§ã¯ãã«è¿½å ã
Haskell.hsã¯ã¿ã¼ã²ããã«å«ããªãããã«Target Membershipã®ãã§ãã¯ãå¤ãã¦ããã
Haskellã®ã³ã¼ããiOSã¢ããªãã«ãæã«ãã«ããããããã«ãã
次ã«ããã«ãããã¨ãã«Haskellã®ã³ã¼ãããã«ããããããã«ãããã¿ã¼ã²ããã®Build Phasesã«Run Scriptsã追å ãã¦ãCompile Sourcesã®åã«ã以ä¸ã®ããã«è¿½å ãã
cd $SRCROOT/App/Haskell PATH=$PATH:/usr/local/bin:$HOME/bin/ghc-ios-scripts/ ghc-ios haskell.hs
Haskellé¨åã®åæåã¨è§£æ¾
Haskellé¨åãå¼ã¶ã¨ãã¯hs_initã§åæåãã¦ãhs_exitã§è§£æ¾ããå¿ è¦ããããããªãã¸ãªãã¸ã§ã¯ããä½ããããã¤ã®åæåã»è§£æ¾ã¨Haskellã®ç¶æ ãä¸è´ããããã«ããã
#import <Foundation/Foundation.h> @interface HaskellBridge : NSObject - (int)x3Int:(int)x; @end
#import "HaskellBridge.h" #import "HTestApp_stub.h" @implementation HaskellBridge - (instancetype)init { self = [super init]; if (self) { hs_init(NULL, NULL); } return self; } - (void)dealloc { hs_exit(); } - (int)x3Int:(int)x { return (int)x3Int(x); } @end
ãµã³ãã«ã¢ããªã®ä½æ
ãã¨ã¯ããããç»é¢ãä½ã£ã¦
ãããªæãã§ä½¿ãã
#import "ViewController.h" #import "Haskell/HaskellBridge.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UITextField *textField; @property (nonatomic) HaskellBridge *bridge; @end @implementation ViewController -(void)viewDidLoad { [super viewDidLoad]; self.bridge = [[HaskellBridge alloc] init]; } - (IBAction)x3Pushed:(id)sender { self.textField.text = [NSString stringWithFormat:@"%d", [self.bridge x3Int:[self.textField.text integerValue]]]; } @end
æååã渡ã
æååã渡ãã«ã¯ãHaskellå´ã§CStringã使ã£ã¦å®ç¾©ãã¦ããã
foreign export ccall repeatString :: Int -> CString -> IO CString repeatString :: Int -> CString -> IO CString repeatString x cstr = do str <- peekCString cstr newCString . foldl (++) "" $ replicate x str
NSStringãcStringUsingEncodingã§Cã®æååãã¤ã³ã¿ãã¨ã£ã¦ãã¦ããã渡ãã°OKã
- (NSString *)repeatString:(NSString *)str count:(int)count { const char *inCstr = [str cStringUsingEncoding:NSUTF8StringEncoding]; const char *outCstr = (const char *) repeatString(count, (HsPtr)inCstr); return [[NSString alloc] initWithCString:outCstr encoding:NSUTF8StringEncoding]; }
åé¡ç¹
æåã®æ¹ã«ãæ¸ãããã©ã64bitæªå¯¾å¿ãªã®ã§ãç¾æç¹ã§ã¯ã¹ãã¢ã«ãªãªã¼ã¹ã§ããªããªã£ã¦ãã¾ã£ã¦ãããã¨ã